共计 2492 个字符,预计需要花费 7 分钟才能阅读完成。
@Autowired 由 Spring 框架定义,用于形容类中的属性后者办法(构造方法,set 办法)。
Spring 框架在我的项目运行时如果发现由它治理的 Bean 对象中有应用 @Autowired 注解形容的属性或者办法,会依照指定规定为属性赋值(DI)。
注入规定
首先检测容器内是否有与属性或办法参数类型相匹配的对象,如果有并且只有一个就间接将这个类型的对象生成注入到属性或办法参数中。证实此论断的办法首先咱们创立一个接口,因为是测试用的所以接口中能够不必写办法~~~~
再创立一个实现此接口的类比方 SoftCache~~~~
在该类下面增加一个 @Component 注解,用来示意该类的对象交给 Spring 框架来治理(创立,应用,存储,销毁)。而后咱们再写一个测试类用来测试 @Autowried 这个注解的作用~~~~
在这个测试类下面要写上这个 @SpringBootTest 这个注解,示意该测试类由 spring 框架治理,然而这个类的对象不会存在 Bean 池中,因为测试类的作用域默认是多例模式(prototype), 在类中申明一个属性,属性类型为刚刚创立的接口类型,这里的属性名能够先随便。再创立一个办法,办法下面要增加注解 @Test 示意单元测试, 办法体里的内容是输入这个属性的值,如果属性没有赋值则输入的值为 null。这个时候咱们运行 testCache 这个办法,控制台打印输出后果为 null。
因为咱们没有给这个属性下面增加一个 @Autowried 注解,也没有在这个属性名字前面给它赋值,所以打印输出的后果是默认值 null(援用类型变量)解决办法能够在该属性下面增加一个 @Autowired 正文,而后 spring 框架就会为咱们生成这个属性类型的实现类对象再打印输出后果是:
输入的后果是这个对象的实现类名字和地址值。
FAQ
1)当一个接口的实现类有多个时,这个接口类型的属性会怎么创建对象呢?
创立一个新的实现类,实现 Cache 接口, 同样的在该类下面增加一个注解 @Component 示意将这类的对象交给 spring 治理,而后运行 Test 办法。
2)当一接口的实现类不止一个时,如果咱们不指定生成哪个实现类类型,Test 运行后会报错: No qualifying bean of type 'com.cy.pj.common.cache.Cache' available: expected single matching bean but found 2: softCache,weakCache
该谬误的意思是,该属性能够创立的实现类不惟一,也就是有多个实现类,Spring 框架底层不晓得你想要哪个实现类对象,所以咱们须要应用 @Qualifier 注解, 这个注解作用是来指定你要创立的实现类是哪个。
@Qualifier 注解里能够写你想要的实现类类名首字母小写其它该大写的中央大写(驼峰命名法)这样 spring 框架就晓得你想要哪个实现类生成对象, 打印输出的后果是。
留神 @Qualifer 外面写的实现类肯定要是实现了你申明的属性的类型的实现类才行,否则会报错。并且此注解要配合 @Autowired 注解应用,否则无奈注入值,输入还是 null。如果不想用 @Qualifer 还有另一种写法就是将申明的属性的属性名写成实现类的类名同样的首字母小写其它该大写的中央大写。
无参结构注入
@Autowired 还能够使用在构造方法上(无参,有参都能够),咱们来测试这个办法,首先从新创立一个类不须要实现 Cache 接口,同样的在这个类上加上一个 @Component 注解让 spring 框架来治理这个类的对象,在这个类中咱们申明一个 Cache 接口类型的属性,并写一个无参构造方法,和一个返回值是 Cache 类型的办法。
而后咱们在写一个测试类用来测试 SeaSerivce 这个类是否能注入值,这个测试类下面要写一个 @SpirngBootTest 注解示意这个测试类交个 Spring 框架治理,这个测试类里申明一个 SeaSerivce 类型的属性因为这个类型的类不是接口所以能够创立这个类的对象(由 Spring 容器创立)。属性上要加上 @Autowired 注解,而后在写一个测试方法,办法体的内容是输入打印在 SerSerivce 类中 Cache 这个接口类的属性的值,通过咱们在 SeaSerivce 类中提供的 get 办法。
输入打印后咱们看到打印的后果为 null,并且除了无参构造方法执行了,还另外执行了一个咱们没有写的办法就是 setCache 办法。当咱们在调用 getCache 这个办法时 Spring 框架会先扫描被 Component 注解过的所有类,在扫描这些类上面是否有 @Autowired 注解有的话就为他们赋值。因为咱们的 Cache cache 这个属性上没有写 @Autowired 注解所以没有主动注入值,打印输出后果为空。如果咱们间接写上 @Autowired 在这个属性上,运行后会报错,起因和下面的谬误是一样的非惟一的实现类。所以咱们要用 set 办法来指定用哪个实现类。
留神要把属性下面的 @Autowired 正文或者删除掉,否则 Spring 扫描到后会间接报错不会持续扫描上面的内容,报错起因也是非惟一实现类。在 set 办法上增加一个 @Autowired 注解并且在参数中要应用 @Qualifier 指定哪个实现类,个别无参结构会配合 set 办法应用。
有参办法注入
在 Seaservice 类中写一个有参构造方法,有参构造方法上的 @Autowired 能够省略不写,须要在参数中指定实现类对象。咱们晓得在创立一个对象时(new 一个对象)会主动调用这个对象的无参结构,如果这个对象外面没有任何构造方法,java 也会为咱们创立一个无参构造方法只是咱们看不见,然而当咱们有了任意一个有参结构,那么 java 就不会为咱们创立无参结构,咱们能够本人写上去,在 SpringBoot 中如果一个类里没有无参构造方法,然么会默认执行有参构造方法这是 SpringBoot 测试类中启动的一个个性。
** 这就是 @Autowired 注解的介绍, 初学 SpringBoot 还有很多中央写的不够谨严,如果有问题能够在评论区提出,我会翻阅材料查改。**
正文完
发表至: springboot
2020-08-28