今天我要在这里说一件让你毁三观的事情。
@Autowired
我曾经看到过很多人都认为在类属性上加一个@Autowired注解是属于自动装配。我们之所以这样认为,就是因为byType引起的,因为很多人认为:@Autowired就是通过bytype来完成注入的。 但是这个bytype不是通过我们提供属性的setXXX()方法,而是通过类反射然后调用:filed.set()来完成的属性注入。如果你非要认为这两个setXXX()方法是一样的我也没有办法,但是这样就意味着你默认了@Autowired这个注解的注入模型是 byType也就是 1。
官网资料:官方介绍了四种注入模型,分别是:no、byName、byType、constructor。
其中no 用0 表示、byName用1表示、byType用2表示、constructor用3表示。
这四种注入模型并没有说到@Autowired ,所以说@Autowired不属于自动装配,而是手动装配。
我们来看一个案例:
ConfigurableListableBeanFactory有一个方法:ignoreDependencyType(); 我们看这个方法的javadoc:忽略自动装配的依赖类型。 就是说如果你忽略某一类型的属性注入,那么注入类型就必须是自动装配。
我们用BeanFactoryPostProcessor 来完成这个案例。
1、我们创建A.Java、B.java 两个类。
public class A {
B b;
public void printBCInfo() {
System.out.println("B:" + b);
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
public class B {
}
2、我们创建一个测试类。将AB添加到环境,并调用A的打印方法。结果如下,
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(A.class,B.class);
applicationContext.refresh();
applicationContext.getBean(A.class).printBCInfo();
}
}
从上面结果知道:B没有注入进来,我们给B添加一个@Autowired
public class A {
@Autowired
B b;
public void printBCInfo() {
System.out.println("B:" + b);
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
再次运行结果如下:
此时B有值。
3、创建一个TestBeanFactoryPostProcessor类让其实现BeanFactoryPostProcessor重写
postProcessBeanFactory()方法如下:
在这里我们可以得到bean工厂,可以利用beanFactory的ignoreDependencyType()这个方法来忽略自动注入的类型。
测试类修改如下:
再次运行结果如下:
发现B还是被注入进来了,并没有被忽略,为什么呢?因为这个方法要求的是,自动装配,我们打印一下A的注入模型。
可以看到,自动注入模型竟然是no 也就是0。所以我们需要更改A的注入模型为byType也就是1。
再次运行结果:
我们发现,修改了A的注入为自动注入,但B还是被注入进来了,为什么?我们是否可以猜想一下,加了@Autowired注解的属性会改变注入类型,如果我们去掉了@Autowired来看看
运行结果如下:
这次B就被忽略注入了。可能有朋友会说,A就没有注入B属性,请注意,我在A中提供了B的set方法,肯定是会注入的。不信我来去掉 .ignoreDependencyType(B.class);再次运行:
这样就更能说明,加了@Autowired这注解的属性,不是自动装配,而是手动装配。
我们再来看一个例子。
新建C.JAVA
public class C {
}
在A中加入C属性,并提供set方法,属性B上添加@Autowired,属性C不加。
修改我们的TestBeanFactoryPostProcessor,添加B、C都会忽略的类型
在测试类的将C注入到容器:
运行结果如下:
B和C两个类完全一样,不一样的是在A中属性B添加了@Autowired注解,属性C没有添加,而结果也是B没有做到忽略注入,而C被忽略注入了,这就更能证明添加了@Autowired这个注解的属性不是自动注入模型了。好了,今天的分享就到这里。