1、传统的方法
- 注解注入
- XML注入
- 继承FactoryBean
Spring中不仅仅有这些传统的方法,还有一些框架内部经常使用的一些注入的方法
2、ImportBeanDefinitionRegistrar动态注入
Spring也是通过ImportBeanDefinitionRegistrar实现了@Component、@Service等注解的动态注入。还有一些框架比如Mybatis中的Mapper接口,以及SpringCloud的FeignClient接口的注入都是通过该接口实现的自定义注册逻辑。接下来我们看一下Mybatis是如何通过ImportBeanDefinitionRegistrar来定义生成Mapper的代理对象的。
SpringBoot项目启动时会装载自动配置的类,所以会加载mybatis启动类的spring.factories下面的MybatisAutoConfiguration类。
我们进入MybatisAutoConfiguration这个自动配置类。
这里是通过@Import注解引入了AutoConfiguredMapperScannerRegistrar,这里是重点
我们看到这里是实现了ImportBeanDefinitionRegistrar,接下来就看看如何生成Mapper的代理对象的。实现了ImportBeanDefinitionRegistrar会调用其中的registerBeanDefinitions的方法。一般的使用我们手动注入bean的时候就可以在该方法中定义一个beanDifinition。我们看看mybatis在这里都做了哪些操作。
这里是定义了一个MapperScannerConfigurer(到这里ImportBeanDefinitionRegistrar的作用其实已经发挥完成了,手动装配了MapperScannerConfigurer,后面则是Mybatis自动生成Mapper代理对象的逻辑)。进入该类
通过它实现的接口我们似乎明白了 最终会执行#postProcessBeanDefinitionRegistry()方法,方法里面的逻辑大概是扫描指定包下面的@Mapper注解的接口,然后获取他们的BeanDefinition,替换BeanDefinition中的class为MapperFactoryBean,然后通过MapperFactoryBean#getObject方法来生成代理对象。
最后通过@Import注解引入ImportBeanDefinitionRegistrar的实现配置类即可。
3、SpringFactoryImportSelector
SpringFactoryImportSelector借助了@Import注解来支持SpringBoot的SPI机制。如SpringFactoryImportSelector<T>则它会加载spring.factories文件里面以Class<T>全限定名为key的所有类。
这里的selectImports方法会被执行。