Spring的注入包括@Resource和@Autowired
@Resource
这里的接口类如果只是注入也可以为实现类。单为什么用接口类呢?是因为:
往往开发中会对实现类做增强,如事务,日志等,实现增强的AOP技术是通过动态代理实现的,而spring默认是JDK动态代理,对实现类对象做增强得到的增强类与实现类是兄弟关系,所以不能用实现类接收增强类对象,只能用接口接收。如:
//接口:IUser //实现类:UserImpl //增强类:UserProxy UserImpl userImpl= new UserImpl(); //通过JDKProxyFactory创建代理对象 JDKProxyFactory factory = new JDKProxyFactory(userImpl); UserProxy userProxy= factory.createProxy();
这个增强类对象userProxy只能强转为IUser,而不能转为UserImpl,因为JDK代理得到的UserProxy 类与UserImpl是兄弟关系而非父子
由于以上原因,如果将对象注入给实现类而非接口的话,在代理时就会报错。
解决方法
让Spring强制使用Cglib代理:(不推荐)
<aop:aspectj-autoproxy proxy-target-class="true"/>
cglib代理类和实现类之间是父子关系,自然可以用父类(实现类)去接收子类对象(代理类对象即增强类对象)。
总结
其实这篇文章这个问题感觉好可笑,为啥用接口?用习惯了呗,但是底层的实现很多人都不知道。使接口本来就是解耦的,还记得java的三大特性吗?- 封装,继承和多态。如果直接实现类,是不是与初衷相违背?
链接:https://www.jianshu.com/p/50cd53040130
@Autowired
@Autowired默认按byType注入:寻找实现了interface的Bean,适用于只有一个Bean实现了接口的情况。
所以在默认情况下@Autowired注释的必须为接口类,否则将会报错