【定义】
在 Spring Boot 场景下,基于约定大于配置的原则,实现 Spring 组件自动装配的目的。
【底层装配技术方式】
(1)Spring 模式注解装配
(2)Spring @Enable 模块装配
(3)Spring 条件装配装配
(4)Spring 工厂加载机制---也是spring里面的一个机制
实现类: SpringFactoriesLoader---装载配置方法,称为spring的工厂
配置资源: META-INF/spring.factories---配置了很多自动装配的东西
结合工厂加载机制实现配置化的加载自动化装配的实现
【实现方式:】
1、激活自动装配 @EnableAutoConfiguration-- 一般在引导类进行标注,
有的时候在引导类看不到@EnableAutoConfiguration注解,是因为在@SpringBootApplication里面包含了这部分内容
就是说当标注了@SpringBootApplication就是标注了@EnableAutoConfiguration
2、实现自动装配 XXXAutoConfiguration
要实现一个XXXAutoConfiguration实现类
可以将模式注解装配、@Enable模块,条件装配,三种方式整合在一起
3、配置自动装配实现 - META-INF/spring.factories
@since 3.2提出的
通过配置的方式把AutoConfiguration的实现配置到 META-INF/spring.factories文件里,通过这个文件写到classpath目录里面来,jar包会加载。
通过KV方式配置 ------key是工厂方法,有个loadFactories方法它的参数factoryClass就是工厂方法,是全类名,值是实现类的全类名,
配置的时候要注意格式,参照spring.factories 源码格式,\换行,空格去掉。
/**
* Load and instantiate the factory implementations of the given type from
* {@value #FACTORIES_RESOURCE_LOCATION}, using the given class loader.
* <p>The returned factories are sorted through {@link AnnotationAwareOrderComparator}.
* <p>If a custom instantiation strategy is required, use {@link #loadFactoryNames}
* to obtain all registered factory names.
* @param factoryClass the interface or abstract class representing the factory
* @param classLoader the ClassLoader to use for loading (can be {@code null} to use the default)
* @throws IllegalArgumentException if any factory implementation class cannot
* be loaded or if an error occurs while instantiating any factory
* @see #loadFactoryNames
*/
public static <T> List<T> loadFactories(Class<T> factoryClass, @Nullable ClassLoader classLoader) {
Assert.notNull(factoryClass, "'factoryClass' must not be null");
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
if (logger.isTraceEnabled()) {
logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames);
}
List<T> result = new ArrayList<>(factoryNames.size());
for (String factoryName : factoryNames) {
result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse));
}
AnnotationAwareOrderComparator.sort(result);
return result;
}
【spring.factories 源码】
激活自动装配EnableAutoConfiguration,下面的这些就会被组装
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
……………………
【小栗子---结合之前的学习】
- 激活自动装配 - @EnableAutoConfiguration
bootstrap包下面----新建引导类EnableAutoConfigurationBootstrap
标注@EnableAutoConfiguration
@EnableAutoConfiguration
public class EnableAutoConfigurationBootstrap {
public static void main(String[] args) {
ConfigurableApplicationContext context = new SpringApplicationBuilder(EnableAutoConfigurationBootstrap.class)
.web(WebApplicationType.NONE)
.run(args);
//关闭上下文
context.close();
}
}
- 实现自动装配 - XXXAutoConfiguration
configuration包下面新建HelloWorldAutoConfiguration实现类
/**
* Hello World 自动装配
*/
@Configuration //Spring 模式注解装配
@EnableHelloWorld //Spring @Enable模块装配
@ConditionalOnSystemProperty(name="user.name",value = "Lenovo") //条件装配
public class HelloWorldAutoConfiguration {
}
说明:
还记得之前学过的Spring模式注解吗?
还记得之前学过的@Enable模块装配吗?--这里采用间接的方式
还记得之前学过的条件装配吗?
好吧,忘记了再瞅几眼~~~
3. 配置自动装配实现 - META-INF/spring.factories ---通过KV方式配置
resources下新建-META-INF目录---新建spring.factories文件
builde一下,会在target下面看到这个文件
2.png
参照源码格式进行配置
META-INF/spring.factories
# 自动装配
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.cbt.diveinspringboot.configuration.HelloWorldAutoConfiguration
【说明】
HelloWorldAutoConfiguration
- 条件判断 :条件是满足的----- user.name == "Lenovo"
- 模式注解: @Configuration
- @Enable模块:
@EnableHelloWorld ->加载 HelloWorldImportSelector ->Selector 加载HelloWorldConfiguration - > HelloWorldConfiguration会自动生成 helloWorld bean
引导类启动后这个bean就会被装载掉
也就是说:
模块装配的时候,前面的条件都满足就会引导出@EnableHelloWorld ->加载 HelloWorldImportSelector ->加载HelloWorldConfiguration - > helloWorld bean
实现了模式注解、@Enable模块、条件装配三种方式整合在一起
4、同样的方式可以对bean进行检查
完善引导类
/**
* {@link @EnableAutoConfiguration}引导类
*/
@EnableAutoConfiguration
public class EnableAutoConfigurationBootstrap {
public static void main(String[] args) {
ConfigurableApplicationContext context = new SpringApplicationBuilder(EnableAutoConfigurationBootstrap.class)
.web(WebApplicationType.NONE)
.run(args);
//helloWorld Bean是否存在
String helloWorld = context.getBean("helloWorld", String.class);
System.out.println("helloWorld Bean : " + helloWorld);
//关闭上下文
context.close();
}
}
运行:
3.png
SpringBoot自动化装配不是SpringBoot的一个特性,是基于Spring Framework的实现。
只是在执行的时候增加了META-INF---spring.factories
所有的API包括条件装配,@Enable模块、模式注解都是spring的一个接口
这个其实就是属于Spring Annotation Programming Model的编程模型,这个编程模型决定了后面springboot的很多特性。
网友评论