看效果
StudentService
一个很普通的方法打印出一句话
UserService
里面包含一个StudentService,并在testStudent方法里调用StudentService里的方法
配置类
测试类及效果
现象说明
我们的UserService里并没有用常见的方法在StudentService上加@Autowired注解,但经测试发现StudentService还是顺利的被注入进去了,这是如何操作的呢?
解释
首先,SpringConfig中可见我们用了一个@Import注解并设置了ImportRegister类
UserService的注册
我们实例化出一个GenericBeanDefinition,设置了beanClass,并用registry注册进Spring容器(有关GenericBeanDefinition的请移步 https://my.oschina.net/u/4523612/blog/4264082 import不了解的请先查一下资料学习一下)
这一步解释了为什么我们能从容器中取出UserService对象来。下面我们解释UserService里为什么能注入StudentService
关键代码
其实关键代码就这一句,就是把BeanDefinition的AutowireMode设置为了AUTOWIRE_BY_TYPE,当AutowireMode为AUTOWIRE_BY_TYPE时Spring再实例化bea时自动按类型给当前类中的属性进行自动注入
我们点进setAutowireMode,可以看到其他常量值的解释
代码浅析
位置: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
这是Spring中非常重要的类,这个类中会对当前的类中的属性进行自动注入
这段代码可以看出当resolvedAutowireMode为AUTOWIRE_BY_NAME或AUTOWIRE_BY_TYPE时,Spring会进行自动注入,而我们最常用的@Service-@Autowired等方式时resolvedAutowireMode为NONE,所以如果不加@Autowired就不会对该属性进行注入,而我们刚刚手动设置为了AUTOWIRE_BY_TYPE,所以就能够实现自动注入
有什么用
当我们写一个工具类,要给别人用时,我们不确定使用者的项目是否用了Spring,如果我们写成@Autowired注解方式,我们的项目将会严重依赖spring,而写成这种做法,不使用spring也可以正常运行,如果要用spring就加入import类即可。
应用举例
mybatis-spring整合包中的SqlSessionDaoSupport就是用这种方式注入了SqlSessionFactory
位置:org.mybatis.spring.support.SqlSessionDaoSupport
来源:oschina
链接:https://my.oschina.net/u/4523612/blog/4280140