Autowired注解

Autowired顾名思义,表示自动注入,如下是Autowired注解的源代码:

  1. @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface Autowired {
  5.  
  6. /**
  7. * Declares whether the annotated dependency is required.
  8. * <p>Defaults to {@code true}.
  9. */
  10. boolean required() default true;
  11.  
  12. }

从Autowired的实现可以看到,Autowired可以用于类的构造方法,类的字段,类的方法以及注解类型上,但是Autowired不能用于类上面。

关于Autowired注解,有如下问题需要解决:

1. Autowired作用在不同的范围上(构造方法,字段、方法)上,它的装配策略如何,按名称还是类型?

2. 为构造方法,字段和方法添加Autowired注解之后,谁来解析这个Autowired注解,完成装配

3. 装配的bean从何处而来,是在Spring的xml文件中定义的bean吗?

从Autowired的javadoc开始

从Autowired的javadoc中得到如下信息

1. AutowiredAnnotationBeanPostProcessor负责扫描Autowired注解,然后完成自动注入

2. 可以对私有的字段使用Autowired进行自动装配,而无需为私有字段定义getter/setter来read/write这个字段

3. 使用Autowired注解的类方法,可以是任意的方法名,任意的参数,Spring会从容器中找到合适的bean进行装配,setter自动注入跟对字段自动注入效果一样

Autowired注解的解析

当项目中使用了Autowired注解时,需要明确的告诉Spring,配置中引用了自动注入的功能,在Spring的配置文件,做法有两种

1. 配置AutowiredAnnotationBeanPostProcessor

2. 使用<context:annotation-config/>。<context:annotationconfig/> 将隐式地向 Spring 容器注册AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorPersistenceAnnotationBeanPostProcessor以及equiredAnnotationBeanPostProcessor 这 4 个 BeanPostProcessor。

实例

1. 实例一:

  • UserSerice依赖的UserDao使用Autowired注解,

  • UserDao没有在Spring配置文件中定义

结果:UserDao为null

2. 实例二:

  • UserSerice依赖的UserDao使用Autowired注解

  • UserDao在Spring配置文件中有定义

结果:UserDao为null

3. 实例三:

  • UserSerice依赖的UserDao使用Autowired注解

  • UserDao在Spring配置文件中有定义

  • Spring中使用<context:annotation-config/>

   结果:UserDao正确注入,在Spring中配置的UserDao的实现,而在UserService中的是UserDao的接口,也就是说,虽然它们类型没有完全匹配,但是由于是实现

关系,Spring仍然能够完成自动注入

4. 实例四:

  • UserSerice依赖的UserDao使用Autowired注解

  • UserDao在Spring配置文件中有定义

  • Spring中配置AutowiredAnnotationBeanPostProcessor

结果:UserDao正确注入,同实例三

5. 实例五:

  • UserSerice依赖的UserDao使用Autowired注解

  • UserDao在Spring配置文件中有两份定义(id不同)

  • Spring中使用<context:annotation-config/>

结果:

1. 如果UserDao的属性名与某个bean的id相同,那么按照属性名和id名称匹配原则,自动装配

2. 如果UserService中定义的UserDao的属性名,与Spring配置文件中的两个id都不同,那么注入失败,异常抛出,提示,无法完整自动装配

结论:

1. 使用Autowired自动装配,必须在Spring的配置文件中使用<context:annotation-config/>来告诉Spring需要进行自动装配扫描(AutowiredAnnotationBeanPostProcessor不推荐使用)

2. Autowired默认按类型进行匹配,当匹配到多个满足条件的bean时,再按照属性名和bean的id进行匹配,如果仍然有多个匹配上或者没有一个匹配上,则抛出异常,提示自动装配失败

3. 在使用Autowired时,可以使用Qualifier注解,显式的指定,当冲突发生时,使用那个id对应的bean

4. Autowired注解自动装配功能完成的是依赖的自动注入,因此,在一个bean中,它依赖的bean可以通过自动注入的方式完成而不需要显式的为它的属性进行注入。但是这些依赖的bean仍然不能省略,还是要在Spring中进行配置,省略的仅仅是bean属性的注入配置代码

Resource注解

Resource注解在功能和目的上,等效于Autowried+Qualifier注解,Resource注解是JSR-250规范的一部分,它定义在JDK的javax.annoation包中,如下是它的定义:

  1. package javax.annotation;
  2.  
  3. import java.lang.annotation.*;
  4. import static java.lang.annotation.ElementType.*;
  5. import static java.lang.annotation.RetentionPolicy.*;
  6.  
  7. /**
  8. * The Resource annotation marks a resource that is needed
  9. * by the application. This annotation may be applied to an
  10. * application component class, or to fields or methods of the
  11. * component class. When the annotation is applied to a
  12. * field or method, the container will inject an instance
  13. * of the requested resource into the application component
  14. * when the component is initialized. If the annotation is
  15. * applied to the component class, the annotation declares a
  16. * resource that the application will look up at runtime. <p>
  17. *
  18. * Even though this annotation is not marked Inherited, deployment
  19. * tools are required to examine all superclasses of any component
  20. * class to discover all uses of this annotation in all superclasses.
  21. * All such annotation instances specify resources that are needed
  22. * by the application component. Note that this annotation may
  23. * appear on private fields and methods of superclasses; the container
  24. * is required to perform injection in these cases as well.
  25. *
  26. * @since Common Annotations 1.0
  27. */
  28. @Target({TYPE, FIELD, METHOD})
  29. @Retention(RUNTIME)
  30. public @interface Resource {
  31. /**
  32. * The JNDI name of the resource. For field annotations,
  33. * the default is the field name. For method annotations,
  34. * the default is the JavaBeans property name corresponding
  35. * to the method. For class annotations, there is no default
  36. * and this must be specified.
  37. */
  38. String name() default "";
  39.  
  40. /**
  41. * The name of the resource that the reference points to. It can
  42. * link to any compatible resource using the global JNDI names.
  43. *
  44. * @since Common Annotations 1.1
  45. */
  46.  
  47. String lookup() default "";
  48.  
  49. /**
  50. * The Java type of the resource. For field annotations,
  51. * the default is the type of the field. For method annotations,
  52. * the default is the type of the JavaBeans property.
  53. * For class annotations, there is no default and this must be
  54. * specified.
  55. */
  56. Class<?> type() default java.lang.Object.class;
  57.  
  58. /**
  59. * The two possible authentication types for a resource.
  60. */
  61. enum AuthenticationType {
  62. CONTAINER,
  63. APPLICATION
  64. }
  65.  
  66. /**
  67. * The authentication type to use for this resource.
  68. * This may be specified for resources representing a
  69. * connection factory of any supported type, and must
  70. * not be specified for resources of other types.
  71. */
  72. AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
  73.  
  74. /**
  75. * Indicates whether this resource can be shared between
  76. * this component and other components.
  77. * This may be specified for resources representing a
  78. * connection factory of any supported type, and must
  79. * not be specified for resources of other types.
  80. */
  81. boolean shareable() default true;
  82.  
  83. /**
  84. * A product specific name that this resource should be mapped to.
  85. * The name of this resource, as defined by the <code>name</code>
  86. * element or defaulted, is a name that is local to the application
  87. * component using the resource. (It's a name in the JNDI
  88. * <code>java:comp/env</code> namespace.) Many application servers
  89. * provide a way to map these local names to names of resources
  90. * known to the application server. This mapped name is often a
  91. * <i>global</i> JNDI name, but may be a name of any form. <p>
  92. *
  93. * Application servers are not required to support any particular
  94. * form or type of mapped name, nor the ability to use mapped names.
  95. * The mapped name is product-dependent and often installation-dependent.
  96. * No use of a mapped name is portable.
  97. */
  98. String mappedName() default "";
  99.  
  100. /**
  101. * Description of this resource. The description is expected
  102. * to be in the default language of the system on which the
  103. * application is deployed. The description can be presented
  104. * to the Deployer to help in choosing the correct resource.
  105. */
  106. String description() default "";
  107. }

Autowried注解,首先根据类型匹配,如果类型匹配到多个,那么在根据属性名和bean的id进行匹配(可以由Qualifier注解强制匹配指定的bean id)。Resource注解则顺序不同,它有如下几种可能的情况:

  • Resource注解指定了name属性和type属性

  策略:首先进行按名称匹配策略: 匹配name属性和bean的id,如果匹配,则判断查找到的bean是否是type属性指定的类型,如果是type属性指定的类型,则匹配成功。如果不是type属性指定的类型,则抛出异常,提示匹配失败;如果name属性跟bean的id不匹配,则抛出异常提示没有bean的id匹配name属性

  • Resource注解指定了name属性,未指定type属性

  策略:查找bean的id为name属性的bean,查找到,不关心类型为什么,都是匹配成功;如果找不到name属性指定的bean id,则匹配失败,抛出异常

  • Resource注解指定了type属性,未指定name属性

  策略:首先进行按名称匹配策略: 匹配属性名和bean的id,如果匹配,则判断查找到的bean是否是type属性指定的类型,如果是type属性指定的类型,则匹配成功。如果不是type属性指定的类型,则抛出异常,提示匹配失败;其次进行按类型匹配策略: 如果属性名跟bean的id不匹配,则查找类型为type的bean,如果仅仅找到一个,自动装配成功,其它情况失败。

  • Resource注解未指定type属性和name属性

   策略:首先进行按属性名匹配策略,匹配则注入成功;如果属性名不匹配,则进行类型匹配策略,只有为一个类型匹配才成功,其他情况都失败

【Spring】Autowired原理及与Resource注解区别的更多相关文章

  1. Spring下的@Inject、@Autowired、@Resource注解区别(转)

    1.@Inject javax.inject JSR330 (Dependency Injection for Java) 这是JSR330中的规范,通过AutowiredAnnotationBean ...

  2. 关于@Autowired和@Resource注解区别

    区分一下@Autowired和@Resource两个注解的区别: 1.@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配 2.@A ...

  3. spring autoWire注解和@resource注解区别

    1.autoWire注解主要是按类型匹配.因为autowire的扫描机制,是按照接口类型来扫描bean的. 而JSR250 @resource注解是通过名称扫描注入的. @autowire注解的扫描方 ...

  4. Spring中静态方法中使用@Resource注解的变量

    开发中,有些时候可能会工具类的静态方法,而这个静态方法中又使用到了@Resource注解后的变量.如果要直接使用 Utils.staticMethod(),项目会报异常:如果不直接使用,还要先 new ...

  5. spring @Autowired和jdk的@Resource区别

    当一个接口只有一个实例时,使用这两个注解的效果是一样的. 当含有两个实例时,非得使用 @Autowired 那么定义的引用类型必须和service实现类定义的名字相同,参照下图 定义第一个servic ...

  6. annotation之@Autowired、@Inject、@Resource三者区别

    一.@Autowired 1.@Autowired是spring自带的注解,通过‘AutowiredAnnotationBeanPostProcessor’ 类实现的依赖注入: 2.@Autowire ...

  7. Spring Autowired原理

    今天来整理一下Spring的自动装配 autowire一节,在这里我们要解决以下问题: 什么是自动装配? 自动装配的意义? 自动装配有几种类型? 如何启用自动装配? 自动装配将引发的问题? 一.什么是 ...

  8. Autowried注解和Resource注解的区别

    目录 1.概述 2.Autowried 3.Resource 4.总结 1.概述 在使用Spring框架的过程中, 依赖注入是必须的, 大多时候会使用Autowried注解来进行依赖注入, 但是也可以 ...

  9. 用@resource注解方式完成属性装配

    注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果. 1 需要修改xml文件的以下信息.    加入下列红色部分的4行 & ...

随机推荐

  1. C# CreateParams的使用(解决闪屏问题)

    <转载自:https://blog.csdn.net/xpwang/article/details/53427479> 窗体和控件的属性CreateParams(这真的是一个属性)很神奇, ...

  2. swust oj 1012

    哈希表(链地址法处理冲突) 1000(ms) 10000(kb) 2542 / 6517 采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用链地址法.建立链表的时候采用尾插法 ...

  3. css3 js 做一个旋转音乐播放开关

    我们经常会看到一些旋转音乐播放开关,今天我也写了一个分享出来,大家需要的话可以参考一下: <!DOCTYPE html> <html lang="en"> ...

  4. 使用BurpSuite进行双文件上传拿Webshell

    首先进入网站后台:(后台界面应该是良精CMS) <ignore_js_op> 在 添加产品 这一栏有个上传文件: <ignore_js_op> 选择一个*.jpg格式的图片进行 ...

  5. JNI实战(二):Java 调用 C

    1. JNI Env 和 Java VM 关系说明 JNIEnv 是 Java的本地化环境,是Java与C的交互的重要桥梁. 在Android上,一个进程对应一个JavaVM,也就是一个app对应一个 ...

  6. java web项目get,post请求参数中文乱码解决

    [转载]原文地址:https://www.cnblogs.com/tom-plus/p/6392279.html 在开发过程中,有时候会碰到get,post请求参数中文乱码. 原因: Http请求传输 ...

  7. [Swift]LeetCode30. 与所有单词相关联的字串 | Substring with Concatenation of All Words

    You are given a string, s, and a list of words, words, that are all of the same length. Find all sta ...

  8. [Swift]LeetCode1009. 十进制整数的补码 | Complement of Base 10 Integer

    Every non-negative integer N has a binary representation.  For example, 5 can be represented as &quo ...

  9. 使用jQuery获取元素的宽度或高度的几种情况

    今天说说使用jQuery获取元素大小的遇到几种情况 使用jQuery获取元素的宽度或高度的有几种情况: 1.使用width(),它只能获取当前元素的内容的宽度: 2.使用innerWidth(),它只 ...

  10. linux 部署mysql

    参考:https://www.cnblogs.com/silentdoer/articles/7258232.html mysql中执行的语句需要在语句结尾使用分号 下载 MySql yum 包  w ...