美文网首页
SpringBoot2.0深度实践学习笔记(四)之Spring

SpringBoot2.0深度实践学习笔记(四)之Spring

作者: Sam_L | 来源:发表于2019-04-23 09:35 被阅读0次

【定义】
在 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

1.png
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,\
……………………

【小栗子---结合之前的学习】

  1. 激活自动装配 - @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();
    }
}
  1. 实现自动装配 - 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的很多特性。

相关文章

网友评论

      本文标题:SpringBoot2.0深度实践学习笔记(四)之Spring

      本文链接:https://www.haomeiwen.com/subject/ukrmgqtx.html