Spring之@Autowired 让你毁三观的自动装配

今天我要在这里说一件让你毁三观的事情。

       我们JAVA程序员经常使用的@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这个注解的属性不是自动注入模型了。好了,今天的分享就到这里。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小tu豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值