Spring Boot . 3 -- Spring Boot Auto_configuration 是如何实现的?

    配置是Spring 框架的重要核心之一,所以Spring 应用能够正常的跑起来肯定是需要配置的,但是使用的Spring Boot 后很多配置没有做,那么AUTO-CONFIGURATION 到底是怎么发生的呢?发生的顺序和步骤是怎样的?怎么实现的呢? 

    在应用中使用Spring Boot的时候,spring-boot-autoconfigure这个jar包会被引入进来,这个Jar包里面包含了一些配置类。这个包里的所有都在应用的claspath上,都有可能在自动配置执行的过程中被用到,从而简化应用的配置工作。这个jar的内容大致是下面这个样子:

   

    箭头指向的基本在ReadingList应用中都有用到,这些配置类通过注解的方式使用,在运行期通过一系列的条件判断进行Bean的加载和配置。在这些配置完成后,一个可用的应用运行环境就准备好了。实现这些配置类的基础是Spring 4.0 提供的Condition 接口,通过实现Condition 接口的matches 方法来进行动态的判定。先来看看Condition 接口怎么用。

    1. Spring 4.0 开始提供的 Condition 接口。

    举个例子。需要在应用中建立一个操作数据库的DBService 类,这个类中要用到JdbcTemplate的实例。那么实例化JdbcTemplate前,首先要保证JdbcTemplate 在应用的classpath上,那怎么判断classpath上是不是有JdbcTemplate?用Condition 接口怎么实现这个判断呢?

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class JdbcTemplateCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        try {
            context.getClassLoader().loadClass("org.springframework.jdbc.core.JdbcTemplate");
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

     这个判断实现完成,如何使用这个判断条件呢?

@Conditional(JdbcTemplateCondition.class)
public DBService dbService() {
    @AutoWire
    JdbcTemplate jdbcTemplate;
    
    // TODO 
}

     DBService 在实例化以前首先要判断 JdbcTemplateCondition,返回true才会继续进行实例化,否则当前的类会被忽略,不进行实例化。

 

2、Spring Boot 实现的Conditional** 形式的注解。

     Spring Boot 实现了一系列的Conditional Annotation。这些基本上是可以见名知意的。下面就是一部分常见的条件注解(Conditional Annotation)。

     没有不要去看所有的条件注解的具体实现,但是为了能够比较明晰的解释Auto-Configuration 的工作过程,将 DataSourceAutoConfiguration 的具体实现写一下,加深下自动配置的理解,也可以学习使用 @Conditional 注解和 接口Condition 的使用。

@Configuration
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@EnableConfigurationProperties({DataSourceProperties.class})
@Import({Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class})
public class DataSourceAutoConfiguration {
   ... ... 
}

    1、第一个注解 @Configuration 这个和xml 配置Bean 是同样的效果,这个就不详细解释了。

    2、第二个注解 @ConditionalOnClass 的意思:在classpath 在上有相应的类的话 返回True,否则返回false。

    3、第三个注解 @EnableConfigurationProperties({DataSourceProperties.class})  允许使用application.properties 文件配置 DataSource 的参数。

    4、第四个注解 @Import 将其参数中的类引入并初始化为一个Bean。

    真正要关注的是第二个注解 ConditionalOnClass,这个注解判断 DataSource 和 EmbededDataBaseType 两个类是否在classpath 上。如果此条件判定为真,开始后续的判定。继而判断当前是否有DataSource 实例,是否是嵌入式的数据,是否有嵌入式的Tomcat 等等。。一些列运行时判定最终决定是否生成配置一个可用的数据源。

3、ReadingList 工程中 Auto-Configuration 工作的过程。

     (1)因为H2在classpath上,因此一个嵌入式的H2 数据库被实例化,这个Bean 是 javax.sql.DataSource 类型的,所以 一个JPA 的接口需要实例化。

     (2)因为 Hibernate Entity Manager 在classpath上,因此启用Hibernate的话,需要auto-configuration 需要实例化 LocalContainerManagerFactory Bean 和 JPAVendorAdapter。

     (3)因为 JPA 在 classpath 上,所以repository 的实例也会被自动创建。

     (4)因为Spring MVC 在classpath上, Spring 的DispatcherServlet 会被实例化。

     (5)因为是web 应用,因此一个资源的handler 会被注册,来处理 resource 目录下的静态资源。

     (6)因为Tomcat 在classpath 上,一个内置的Tomcat 容器会被启动承载和提供服务。

 

4、其实不知道也不影响用Spring Boot 实现业务嘛。

     这一篇不写也罢。

     举个用Condition 的例子:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

// 如果在applicaton.properties 文件中 见env.test=1 那么对应的类会被加载 @ConfigurationProperties("env.test") public class TestEnableCondition implements Condition { public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { String test = conditionContext.getEnvironment().getProperty("env.test"); int isTest; try { isTest = Integer.valueOf(test); } catch (Exception e) { isTest = 0; } return isTest==1; } }
@Conditional(TestEnableCondition.class)
@Controller
@RequestMapping(value = "/{param}")
public class TestController {
   ... ... 
}

 

转载于:https://www.cnblogs.com/tju-gsp/p/6275021.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值