Spring注解的区别
Posted
技术标签:
【中文标题】Spring注解的区别【英文标题】:Difference between Spring annotations 【发布时间】:2012-08-27 02:15:46 【问题描述】:问题:
1) @Component
和 @Configuration
的区别?
我已经读到两者都消除了将接线代码放入 XML 的必要性,但没有得到它们之间的区别。
2)@Autowired
、@Inject
和@Resource
有什么区别?
- 什么时候使用?
- 各自的优缺点是什么?
【问题讨论】:
见:***.com/a/41802044/2167531 【参考方案1】:@Component
和@Configuration
确实是非常不同类型的注解。
@Component
和类似的注解(@Service
、@Repository
等)和它的 JSR-330 对应的 @Named
允许您声明要通过使用 <context:component-scan/>
或 @987654335 进行自动扫描来获取的 bean @它们为类注册bean定义,所以它们大致相当于在XML中用<bean ... />
标签声明指定的bean。此 bean 类型将遵循标准代理创建策略。
@Configuration
注释被设计为 XML 配置文件的替换。要创建 @Configuration
注释 bean,Spring 将始终使用 CGLIB
子类化 @Configuration
注释类,覆盖其 @Bean
注释方法以将其替换为 bean 查找方法,以使单例 bean 仅创建一次。 (Spring 不使用CGLIB
来拦截 normal Spring beans 的 internal 方法调用,而是创建一个单独的代理实例(与 JDK 代理相同)。做因此允许使用代理来避免基数不匹配 - 例如,代理单例可以获取当前会话 bean,这仅通过类继承是不可能的。)。尽管如此,@Configuration
带注释的类仍然能够使用带注释的(@Autowired
、@Inject
等)字段和属性从容器请求 bean(甚至还有其他 @Configuration
带注释的 bean)。
示例来自documentation的 4.12.5 部分
@Configuration
public class AppConfig
@Bean
public ClientService clientService1()
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
@Bean
public ClientService clientService2()
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
@Bean
public ClientDao clientDao()
return new ClientDaoImpl();
在上面的示例中,只会创建一个ClientDao
实例。
@Autowired
是 Spring 注解,而 @Inject
是 JSR-330 注解。
@Inject
等价于 @Autowired
或 @Autowired(required=true)
,但您无法使用 JSR-330 @Inject
annotation 获得 @Autowired(required=false)
行为。此注解始终使用按类型自动装配。
Spring 以一种相当特殊的方式实现了JSR-250 @Resource
注解。 @Resource
最初是为在 Java EE 中定位 JNDI 资源而设计的,但 Spring 扩大了它的适用性,使其可以连接到容器中的任何 bean(JNDI 资源在 SimpleJndiBeanFactory 的帮助下作为 bean 可用)。
对应bean的名称可以指定为@Resource
注解的name
属性,如果没有指定名称,则使用被注解的字段或属性的名称。另一个奇怪的特性是,如果没有找到具有属性名称的 bean,spring 将回退到按类型布线。
示例
假设我们在容器中有一个名为 beanAlpha 的 AlphaClass
bean 和一个 BetaClass
bean beanBeta。
@Resource
BetaClass something; // Wires to beanBeta - by-type
@Resource
BetaClass beanAlpha; // Will throw exception, because "beanAlpha" is not BetaClass -> it's a bad idea to use @Resource as a replacement of @Autowired
@Resource
Object beanAlpha; //Wires to beanAlpha - by-name
因此,在使用 @Resource
注释时始终明确指定资源名称是一个好习惯。
文档
Spring annotations
Bean standard annotations
正如 shevchik 所指出的,update 修复了 JSR 引用。 DI 特定注解由 Google(Guice Framework)和 SpringSource(Spring Framework)工程师开发的 JSR-330 提供。 @Resource
是基于 JNDI 的,由 JSR-250 提供。
【讨论】:
"@Named 和 @Inject" 是 JSR330 注释。 “@Resource、@PostConstruct、@PreDestroy”是 JSR250。【参考方案2】:@Component
等价于<bean>
,@Configuration
等价于<beans>
。
【讨论】:
如果这是真的,那么为什么它们似乎可以互换使用? 简洁明了@Component
和 @Configuration
本质上是相同的。我可以看到的主要区别是@Configuration
类上的任何@Bean
方法都将被记忆(在第一次执行时缓存,以便所有未来的请求只返回相同的对象而不执行该方法)。【参考方案3】:
在上面的大多数答案中,用户建议说@Component 和@Configuration 用于不同的目的。但我没有看到它在现实中发生。
但我有一个简单的 Spring MVC 应用程序。
@Configuration
public class SpringConfiguration
@Bean
public InternalResourceViewResolver initViewResolver()
InternalResourceViewResolver x = new InternalResourceViewResolver();
x.setPrefix("/WEB-INF/jsp/");
x.setSuffix(".jsp");
return x;
这个主类工作正常,即使它被注释为@Component 而不是@Configuration。
如果您有使用@Bean 注释的方法,则类似地在注释为@Component 的类中,这些bean 是在加载上下文时创建的。
所以我认为,为了代码的可读性,我们应该将主配置类标记为@Configuration,其他类使用@Component。 实际执行明智似乎没有区别。
【讨论】:
配置和组件之间至少有一个区别。配置允许您的 Bean 具有 bean 间的依赖关系,而 Component 则没有。 docs.spring.io/spring/docs/current/spring-framework-reference/…@Configuration
类上的任何 @Bean
方法都将被记忆(在第一次执行时缓存,以便所有未来的请求只返回相同的对象而不执行该方法)。 @Component
s 的情况并非如此。他们的方法每次都会运行,每次都可能返回一个新对象(即使该对象可能是 .equals
与所有先前执行的返回值等效)。见:***.com/a/41802044/2167531【参考方案4】:
关于@Autowired
、@Inject
和@Resource
之间的区别,您可以查看here。在这里您可以进行全面的描述和比较。
与第一个区别有关:@Configuration
用于替代基于XML
的配置,即。它将类标记为用于基于Java
的配置,请参阅here。反过来,@Component
实际上用于将类标记为要由Spring
实例化的类,而@Configuration
由@Component
注释进行元注释。
@Component
和 @Configuration
用途不同,因此比较它们没有意义。
【讨论】:
在您提到的链接中还指出,使用 @Configuration 注释类表明该类可以被 Spring IoC 容器用作 bean 定义的来源。所以我真的不明白它和@Component 有什么不同? 根据 Spring Java 文档,真正的区别在于 @Configuration 注释类'inter-bean references' are guaranteed to respect scoping and AOP semantics
(引用自 here)。在@Component 注释类scoping semantics are not respected ... for inter-bean method invocations in this mode
中。根据ticket,这种差异也没有得到很好的记录。【参考方案5】:
1) 如果您需要 XML 配置,请忽略 @Configuration,因为这仅对基于 Java 的配置有用。 XML 配置可能最适合不熟悉 Spring 的人,因为有更多示例可用。
@Component 注释类在组件扫描期间被拾取。使用它们来标记您想要作为 Spring bean 公开的类。同样,您可以在 XML 配置中声明所有 bean,完全忽略 @Component。
2) 如果您愿意将您的应用程序绑定到 Spring,那么请使用 @Autowire 而不是 javax 等效的 @Inject。我建议接受对 Spring 的依赖是最好的开始方式。
【讨论】:
以上是关于Spring注解的区别的主要内容,如果未能解决你的问题,请参考以下文章
Spring中@Autowired注解@Resource注解的区别(转)
Spring中@Autowired注解@Resource注解的区别
Spring中@Autowired注解@Resource注解的区别
Spring中@Autowired注解@Resource注解的区别