springboot自动装配原理

  • Post author:
  • Post category:其他




24. springboot自动装配原理

之前搭建ssm框架的时候,需要些3个xml配置文件,用来配置mybatis、spring、springmvc组件。然而现在有了springboot,我们甚至可以0配置直接启动web服务了。为什么springboot不需要进行配置了呢?其实他们自动帮我们配好了。下面整理下如何自动配置的。依springmvc为例子。

  1. 在项目的maven的pom文件导入

    <artifactId>spring-boot-starter-web</artifactId>

    即可
  2. 项目的main程序入口的注解

    @SpringBootApplication

    中包括

    @EnableAutoConfiguration

    注解启用自动配置功能
  3. 在注解

    @EnableAutoConfiguration

    中包括

    @Import(AutoConfigurationImportSelector.class)

    注解。
  4. 解释一下注解

    @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);
 }
  1. 看,通过以上逻辑成功把一些bean实例化到ioc里面了,然后我们使用@Autowired取出bean

    例如我们导入了redis的starter依赖,那么我们就可以在service里面直接使用RedisTemplate



版权声明:本文为weixin_48835367原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。