问题:
1)@Component
和@Configuration
之间的差异?
我已经读过,两者都删除了将代码放入XML中的必要性,但没有区分这些代码。
2)@Autowired
,@Inject
和@Resource
之间有什么区别?
- 什么时候使用?
- 每个人的利弊是什么?
答案 0 :(得分:54)
@Component
和@Configuration
确实是非常不同的注释类型。
@Component
和类似的注释(@Service
,@Repository
等)及其JSR-330对应@Named
允许您声明要选择的bean通过使用<context:component-scan/>
或@ComponentScan
进行自动扫描,他们注册了类的bean定义,因此它们大致相当于在XML中声明带有<bean ... />
标记的指定bean。此bean类型将遵循标准代理创建策略。
@Configuration
注释被设计为替换XML配置文件。要创建@Configuration
带注释的bean,Spring将始终使用CGLIB
子类化@Configuration
带注释的类,覆盖其@Bean
带注释的方法,将其替换为bean查找方法以生成单例bean只能创建一次。 (Spring不使用CGLIB
来拦截普通 Spring bean的内部方法调用,而是创建一个单独的代理实例(与JDK代理一样)这样做允许使用代理来避免基数不匹配 - 例如,代理单例可以获取当前会话bean,这对于类继承是不可能的。)。尽管如此,@Configuration
带注释的类仍然可以使用带注释的(@Autowired
,@Inject
等)字段和属性来请求bean(甚至其他@Configuration
带注释的bean)来自容器。
示例
@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 @Autowired(required=false)
注释获得@Inject
行为。此注释始终使用按类型自动装配。
Spring以一种相当特殊的方式实现JSR-250 @Resource
注释。 @Resource
最初设计用于在Java EE中查找JNDI资源,但Spring扩展了它的适用性,使得可以连接到容器中的任何bean(JNDI资源在SimpleJndiBeanFactory的帮助下可用作bean)。
可以将相应bean的名称指定为name
注释的@Resource
属性,如果未指定名称,则将使用带注释的字段或属性的名称。另一个奇怪的特征是,如果没有找到具有属性名称的bean,spring将回退到by-type接线。
示例强>
想象一下,我们在容器中有一个名为 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
注释时始终明确指定资源名称是一种很好的做法。
<强>文档强>
更新修复了 shevchik 指出的JSR引用。 DI特定注释由JSR-330提供,JSR-330由Google(Guice Framework)和SpringSource(Spring Framework)工程师开发。 @Resource
基于JNDI,由JSR-250提供。
答案 1 :(得分:22)
@Component
相当于<bean>
,
@Configuration
相当于<beans>
。
答案 2 :(得分:5)
在上面的大多数答案中,用户建议说@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。 实际执行明显没有区别。
答案 3 :(得分:2)
根据@Autowired
,@Inject
和@Resource
之间的区别,您可以查看here。在这里你可以进行彻底的描述和比较。
第一个区别是什么:@Configuration
用于替代基于XML
的配置,即。它将类标记为用于基于Java
的配置的类,请参阅here。反过来,@Component
实际上用于将类标记为Spring
实例化的类,而@Configuration
由@Component
注释进行元注释。
@Component
和@Configuration
有不同的用途,因此比较它们没有意义。
答案 4 :(得分:2)
1)如果您想要XML配置,请忽略@Configuration,因为这仅对基于Java的配置有用。对于不熟悉Spring的人来说,XML配置可能是最好的,因为有更多可用的例子。
在组件扫描期间拾取@Component注释类。使用它们来标记要作为Spring bean公开的类。同样,您可以在XML配置中声明所有bean,并完全忽略@Component。
2)如果您乐意将应用程序绑定到Spring,那么请使用@Autowire而不是javax等效的@Inject。我建议接受对Spring的依赖是最好的开始方式。