问题:
@Component
1)和之间的区别@Configuration
?
我已经读过两者都消除了将代码放入 XML 中的必要性,但没有得到它们之间的区别。
@Autowired
2 )@Inject
和之间有什么区别@Resource
?
- 什么时候使用?
- 各自的优缺点是什么?
问题:
@Component
1)和之间的区别@Configuration
?
我已经读过两者都消除了将代码放入 XML 中的必要性,但没有得到它们之间的区别。
@Autowired
2 )@Inject
和之间有什么区别@Resource
?
- 什么时候使用?
- 各自的优缺点是什么?
@Component
并且@Configuration
确实是非常不同类型的注释。
@Component
和类似的注解(@Service
,@Repository
等)及其对应的JSR-330@Named
允许您声明要通过自动扫描获取的 bean, <context:component-scan/>
或者@ComponentScan
它们为类注册 bean 定义,因此它们大致相当于用XML 中的<bean ... />
标记。此 bean 类型将遵守标准代理创建策略。
@Configuration
annotation 被设计为 XML 配置文件的替换。为了创建带@Configuration
注释的 bean,Spring 将始终使用CGLIB
子类化带@Configuration
注释的类,覆盖其@Bean
带注释的方法以将其替换为 bean 查找方法,以使单例 bean 仅创建一次。(Spring 不CGLIB
用于拦截普通Spring bean 的内部方法调用,而是创建一个单独的代理实例(与 JDK 代理相同)。这样做允许使用代理来避免基数不匹配 - 例如代理单例可以获取当前会话 bean,仅通过类继承是不可能的。)。尽管如此,带注释的类仍然可以使用带注释的(,@Configuration
@Autowired
@Inject
等)从容器中请求 bean(甚至还有其他@Configuration
带注释的 bean)的字段和属性。
来自文档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
or @Autowired(required=true)
,但您无法@Autowired(required=false)
使用 JSR-330@Inject
注释获得行为。此注释始终使用按类型自动装配。
Spring 以一种相当特殊的方式实现JSR-250 @Resource
注释。@Resource
最初是为在 Java EE 中定位 JNDI 资源而设计的,但 Spring 扩大了它的适用性,使其可以连接到容器中的任何 bean(JNDI 资源在SimpleJndiBeanFactory的帮助下作为 bean 可用)。对应bean的名称可以指定为注解的name
属性@Resource
,如果没有指定名称,则使用被注解的字段或属性的名称。另一个奇怪的特性是,如果没有找到具有属性名称的 bean,spring 将回退到按类型布线。
示例
假设我们在容器中有一个AlphaClass
名为beanAlpha的 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 特定注解由 Google(Guice Framework)和 SpringSource(Spring Framework)工程师开发的 JSR-330 提供。@Resource
是基于 JNDI 并由JSR-250提供的。
@Component
等价于<bean>
,
@Configuration
等价于<beans>
。
在上面的大多数答案中,用户建议说@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。实际执行明智似乎没有区别。
1) 如果您想要 XML 配置,则忽略 @Configuration,因为这仅对基于 Java 的配置有用。XML 配置可能最适合不熟悉 Spring 的人,因为有更多示例可用。
@Component 注解的类在组件扫描期间被拾取。使用它们来标记您想要作为 Spring bean 公开的类。同样,您可以在 XML 配置中声明所有 bean 并完全忽略 @Component。
2) 如果您乐于将应用程序绑定到 Spring,请使用 @Autowire 而不是 javax 等效的 @Inject。我建议接受对 Spring 的依赖是最好的开始方式。