24. springboot自动装配原理
之前搭建ssm框架的时候,需要些3个xml配置文件,用来配置mybatis、spring、springmvc组件。然而现在有了springboot,我们甚至可以0配置直接启动web服务了。为什么springboot不需要进行配置了呢?其实他们自动帮我们配好了。下面整理下如何自动配置的。依springmvc为例子。
-
在项目的maven的pom文件导入
<artifactId>spring-boot-starter-web</artifactId>
即可 -
项目的main程序入口的注解
@SpringBootApplication
中包括
@EnableAutoConfiguration
注解启用自动配置功能 -
在注解
@EnableAutoConfiguration
中包括
@Import(AutoConfigurationImportSelector.class)
注解。 -
解释一下注解
@Import(xxx)
作用:类似于@Component注解,把xxx进行实例化并且放入Ioc容器中。@Import只能用在类上 ,@Import通过快速导入的方式实现把实例加入spring的IOC容器中。其中xxx的写法有三种
- 直接填对应的class数组,class数组可以有0到多个。
@Import({ 类名.class , 类名.class... })
- 自定义类Myclass并实现ImportSelector接口的方法selectImports
public class Myclass implements ImportSelector {
//既然是接口肯定要实现这个接口的方法
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//返回值: 就是我们实际上要导入到容器中的组件全类名
return new String[0];
}
}
然后使用
@Import({ Myclass.class })
-
自定义类Myclass2并实现ImportBeanDefinitionRegistrar接口的方法registerBeanDefinitions
类似于第二种ImportSelector用法,相似度80%,只不过这种用法比较自定义化注册,具体如下:public class Myclass2 implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { //指定bean定义信息(包括bean的类型、作用域...) RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemo4.class); //注册一个bean指定bean名字(id) beanDefinitionRegistry.registerBeanDefinition("TestDemo4444",rootBeanDefinition); } }
5. 回过头来看自动装配`@Import(AutoConfigurationImportSelector.class)`注解
看源码得出`AutoConfigurationImportSelector`类实现了`interface ImportSelector`接口selectImports方法,所以看一下`selectImports`的具体逻辑。
```java
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
...
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
重点是调用了
getAutoConfigurationEntry
方法:
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
...
//把org.springframework.boot.autoconfigure依赖jar包的MATE-INF/spring.factories文件的内容多个EnableAutoConfiguration=xxxAutoConfiguration载入到数组
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
//过滤:结合本项目pom文件中的依赖,进行删除没有的bean
configurations = getConfigurationClassFilter().filter(configurations);
return new AutoConfigurationEntry(configurations, exclusions);
}
-
看,通过以上逻辑成功把一些bean实例化到ioc里面了,然后我们使用@Autowired取出bean
例如我们导入了redis的starter依赖,那么我们就可以在service里面直接使用RedisTemplate
版权声明:本文为weixin_48835367原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。