简体   繁体   English

Spring注释之间的区别

[英]Difference between Spring annotations

Questions: 问题:

1) Difference between @Component and @Configuration ? 1) @Component@Configuration之间的区别?

I have read that both remove the necessity of wiring code to be put in XML, but did not get the difference between these. 我已经读过,两者都删除了将代码放入XML中的必要性,但没有区分这些代码。

2) What are the differences between @Autowired , @Inject and @Resource ? 2)@ @Autowired ,@ @Inject@Resource之间有什么区别?
- Which one to use when? - 什么时候使用?
- What are the pros/cons of each? - 每个的优点/缺点是什么?

@Component and @Configuration are indeed very different types of annotations. @Component@Configuration确实是非常不同的注释类型。

@Component and similar annotations ( @Service , @Repository , etc. )and its JSR-330 counterpart @Named allow you to declare beans that are to be picked up by autoscanning with <context:component-scan/> or @ComponentScan they register the bean definition for the classes, so they are roughly equivalent to declaring the specified beans with the <bean ... /> tag in XML. @Component和类似的注释( @Service @Repository@Service @Repository等)和它的JSR-330对应@Named允许你通过自动扫描来声明要通过<context:component-scan/>@ComponentScan注册的bean来注册它们类的bean定义,因此它们大致相当于在XML中使用<bean ... />标记声明指定的bean。 This bean types will adhere to the standard proxy creation policies. 此bean类型将遵循标准代理创建策略。

@Configuration annotation was designed as the replacement of the XML configuration file. @Configuration注释被设计为替换XML配置文件。 To create @Configuration annotated beans, Spring will always use CGLIB to subclass the @Configuration annotated class, overriding its @Bean annotated method to replace it with the bean lookup method to make singleton beans to be created only once. 要创建@Configuration注释的bean,Spring将始终使用CGLIB子类化@Configuration注释的类,覆盖其@Bean注释的方法,将其替换为bean查找方法,以使单个bean只创建一次。 (Spring does not use CGLIB to intercept internal method calls of normal Spring beans, it creates a separate instance of proxy instead(same way like JDK proxy does). Doing so allows to use proxies to avoid cardinality mismatch - for example a proxy singleton can fetch current session bean, which is not possible with class inheritance only. ). (Spring不使用CGLIB拦截普通 Spring bean的内部方法调用,而是创建一个单独的代理实例(与JDK代理一样)。这样做允许使用代理来避免基数不匹配 - 例如代理单例可以获取当前会话bean,这对于类继承是不可能的。)。 Despite that, @Configuration annotated classes are still able to use annotated( @Autowired , @Inject etc.) fields and properties to request beans (and even other @Configuration annotated beans too) from the container. 尽管如此, @Configuration注释类仍然可以使用带注释的(@ @Autowired ,@ @Inject等)字段和属性来从容器中请求bean(甚至其他@Configuration注释的bean)。

Example from 4.12.5 section of the 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();
  }
}

in the example above only one ClientDao instance will be created. 在上面的示例中,将只创建一个ClientDao实例。

@Autowired is Spring annotation, while @Inject is a JSR-330 annotation. @Autowired是Spring注释,而@Inject是JSR-330注释。 @Inject is equivalent to @Autowired or @Autowired(required=true) , but you can't get @Autowired(required=false) behavior with the JSR-330 @Inject annotation. @Inject相当于@Autowired@Autowired(required=true) ,但是你无法使用JSR-330 @Inject注释获得@Autowired(required=false)行为。 This annotation always uses by-type autowiring. 此注释始终使用按类型自动装配。

Spring implements JSR-250 @Resource annotation in a rather special way. Spring以一种相当特殊的方式实现了JSR-250 @Resource注释。 @Resource was originally designed for locating JNDI resources in Java EE, but Spring widens it applicability making it possible to wire to any bean in the container(JNDI resources are available as beans with the help of SimpleJndiBeanFactory ). @Resource最初设计用于在Java EE中查找JNDI资源,但Spring扩展了它的适用性,使得可以连接到容器中的任何bean(JNDI资源在SimpleJndiBeanFactory的帮助下可用作bean )。 The name of the corresponding bean can be specified as name attribute of @Resource annotation, if no name was specified, then the name of the annotated field or property will be used. 可以将相应bean的名称指定为@Resource注释的name属性,如果未指定名称,则将使用带注释的字段或属性的名称。 Another strange feature is that if no bean with the property name was found spring will fallback to by-type wiring. 另一个奇怪的特征是,如果没有找到具有属性名称的bean,则spring将回退到by-type布线。

Example Imagine that we have an AlphaClass bean named beanAlpha and a BetaClass bean beanBeta in the container. 例如假设我们有一个AlphaClass名为beanAlpha豆和BetaClassbeanBeta在容器中。

@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

So it's a good practice to always specify resource name explicitly when using @Resource annotation. 因此,在使用@Resource注释时始终明确指定资源名称是一种很好的做法。

Documentation 文档

Spring annotations 春天注释

Bean standard annotations Bean标准注释

update fixed JSR references as shevchik has pointed out. 更新固定的JSR引用,正如shevchik指出的那样。 DI specific annotations are provided by JSR-330, which was developed by Google (Guice Framework) and SpringSource(Spring Framework) engineers. DI特定注释由JSR-330提供,JSR-330由Google(Guice Framework)和SpringSource(Spring Framework)工程师开发。 @Resource is JNDI based and provided by JSR-250 . @Resource是基于JNDI的,由JSR-250提供

@Component is equivalent to <bean> , @Component相当于<bean>
@Configuration is equivalent to <beans> . @Configuration相当于<beans>

In most the answers above, users suggest to say that @Component and @ Configuration serve different purposes. 在上面的大多数答案中,用户建议说@Component和@Configuration用于不同的目的。 But I do not see it happening in reality. 但我不认为它发生在现实中。

But I have a simple Spring MVC application. 但我有一个简单的Spring MVC应用程序。

@Configuration
    public class SpringConfiguration {

@Bean
public  InternalResourceViewResolver initViewResolver(){
    InternalResourceViewResolver x = new InternalResourceViewResolver();
    x.setPrefix("/WEB-INF/jsp/");
    x.setSuffix(".jsp");
    return x;
}

}

This main class works fine even if it is annotated as @Component instead of @Configuration. 即使注释为@Component而不是@Configuration,这个主类也能正常工作。

Similarly inside a class annotated as @Component if you have methods annotated with @Bean, those beans are created when context is loaed. 类似地,在注释为@Component的类中,如果您有使用@Bean注释的方法,那么在上下文被加载时会创建这些bean。

So I think, it is just for code readability that we should mark main configuration class as @Configuration and other classes with @Component. 所以我认为,只是为了代码可读性,我们应该将主配置类标记为@Configuration,并将其他类标记为@Component。 Actual execution wise there seems no difference. 实际执行明显没有区别。

On the difference between @Autowired , @Inject and @Resource you can look here . 关于@ @Autowired ,@ @Inject@Resource之间的区别,你可以看看这里 Here you can thorough description and comparison. 在这里你可以进行彻底的描述和比较

What concerns the first difference: @Configuration is used as replacement for XML -based configuration, ie. 第一个区别是什么: @Configuration用于替换基于XML的配置,即。 it marks classes as the ones used for Java -based configuration, see here . 它将类标记为用于基于Java的配置的类,请参见此处 In turn, @Component is actually used to mark classes as the ones to be instantiated by Spring and @Configuration is meta-annotated by @Component annotation. 反过来, @Component实际上用于将类标记为要由Spring实例化的类,而@Configuration@Component注释进行元注释。

@Component and @Configuration serve different purposes so it doesn't make sense to compare them. @Component@Configuration用于不同的目的,因此比较它们没有意义。

1) If you want XML configuration, then ignore @Configuration, as this is only useful for Java-based config. 1)如果您需要XML配置,请忽略@Configuration,因为这仅对基于Java的配置有用。 XML config is probably best for someone unfamiliar with Spring as there are more examples available. 对于不熟悉Spring的人来说,XML配置可能是最好的,因为有更多可用的示例。

@Component annotated classes are picked up during component scanning. 在组件扫描期间拾取@Component注释类。 Use them to label classes that you want to expose as Spring beans. 使用它们来标记要作为Spring bean公开的类。 Again, you can just declare all of your beans in the XML config and ignore @Component altogether. 同样,您可以在XML配置中声明所有bean,并完全忽略@Component。

2) If you are happy to tie your application to Spring, then use @Autowire rather than the javax equivalent @Inject. 2)如果您乐意将应用程序绑定到Spring,那么请使用@Autowire而不是javax等效的@Inject。 I'd suggest that accepting a dependency to Spring is the best way to start. 我建议接受对Spring的依赖是最好的开始方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring MongoDB - @Indexed 和 @Field 注释之间的区别 - Spring MongoDB - Difference between @Indexed and @Field annotations Spring 编译时和运行时注解的区别 - Difference between compile time & run time annotations of Spring 在Spring框架中使用@Import和@ImportResource注释有什么区别? - What is the difference between the use of @Import and @ImportResource annotations in Spring framework? Spring 中的@Component、@Repository 和@Service 注解有什么区别? - What's the difference between @Component, @Repository & @Service annotations in Spring? spring javaconfig,xml config和annotations之间的性能差异 - Performance difference between spring javaconfig, xml config and annotations 声明注释和类型注释之间的区别 - Difference between declaration annotations and type annotations Hibernate - 注释和公共注释之间的区别? - Hibernate - difference between annotations and commons-annotations? @Inject 和 @ValueMapValue 注解的区别 - Difference between @Inject and @ValueMapValue annotations 两个@RequestMapping批注之间的区别 - Difference between two @RequestMapping annotations Spring 验证:Class Attributes VS Constructor Parameters 中验证注解的区别 - Spring validation: Difference between validation annotations in Class Attributes VS Constructor Parameters
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM