SpringBoot如何实现自动装配

目录

1、什么是自动配置

1.1、引入redisTemplate

1.2、引入transactionTemplate

1.3、使用@ConfigurationProperties

2、工作原理

2.1、bean的自动配置

2.2、属性的自动配置

3、自动配置的生效条件


1、什么是自动配置

1.1、引入redisTemplate

只要在pom.xml文件中引入 spring-boot-starter-data-redis-xxx.jar 包,然后只要在配置文件中配置redis连接,如:

spring.redis.database = 0
spring.redis.timeout = 10000
spring.redis.host = localhost
spring.redis.port = 6379
spring.redis.pattern = 1

就可以在service方法中直接注入StringRedisTemplate对象的实例,可以直接使用了。有没有想过这是为什么?

@Autowired
private StringRedisTemplate stringRedisTemplate;

1.2、引入transactionTemplate

在项目中只要引入spring-boot-starter-xxx.jar,事务就自动生效了,并且可以直接在service方法中直接注入TransactionTemplate,用它开发编程式事务代码。是不是很神奇?这又是为什么?

1.3、使用@ConfigurationProperties

使用@ConfigurationProperties可以把指定路径下的属性,直接注入到实体对象中,看看下面这个例子:

@Data
@Component
@ConfigurationProperties("jump.threadpool")
public class ThreadPoolProperties {

    private int corePoolSize;
    private int maxPoolSize;
    private int keepAliveSeconds;
    private int queueCapacity;
}

只要application.properties这样配置,就可以自动注入到上面的实体中

jump.threadpool.corePoolSize=8
jump.threadpool.maxPoolSize=16
jump.threadpool.keepAliveSeconds=10
jump.threadpool.queueCapacity=100

没错,这三个例子都是SpringBoot自动配置在起作用,分为两种情况:bean的自动配置 和 属性的自动配置。

2、工作原理

2.1、bean的自动配置

Spring Boot的启动类上有一个@SpringBootApplication注解,这个注解是Spring Boot项目必不可少的注解。

先看看@SpringBootApplication注解

它上面定义了另外一个注解:@EnableAutoConfiguration 

该注解的关键功能由@Import提供,其导入的AutoConfigurationImportSelectorselectImports()方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有具有META-INF/spring.factories的jar包下面key是EnableAutoConfiguration全名的,所有自动配置类。

看看SpringBoot的spring-boot-autoconfigure-xxx.jar

该jar包里面就有META-INF/spring.factories文件。

这个spring.factories文件是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个xxxxAutoConfiguration的类名的列表,这些类名以逗号分隔。

@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上。在SpringApplication.run(...)的内部就会执行selectImports()方法,找到所有JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中。

SpringApplication.run(...)方法怎么调到selectImports()方法的

加载过程大概是这样的:

SpringApplication.run(...)方法 》

AbstractApplicationContext.refresh()方法 》

invokeBeanFactoryPostProcessors(...)方法 》

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(...) 方法 》

ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(..)方法 》

AutoConfigurationImportSelector.selectImports

该方法会找到自动配置的类,并给打了@Bean注解的方法创建对象。

postProcessBeanDefinitionRegistry方法是最核心的方法,它负责解析@Configuration@Import@ImportSource@Component@ComponentScan@Bean等,完成bean的自动配置功能。

回到刚刚第二个例子TransactionTemplate为什么可以直接引用?

是因为在spring-boot-autoconfigure-xxx.jar的spring.factories配置文件中,EnableAutoConfiguration全类名下配置了TransactionAutoConfiguration全类名,SpringBoot在启动的时候会加载这个类。

 

 而TransactionAutoConfiguration类是一个配置类,它里面创建TransactionTemplate类的实例。

 这样在其他地方就可以直接注入TransactionTemplate类的实例。

2.2、属性的自动配置

属性的自动配置是通过ConfigurationPropertiesBindingPostProcessor类的postProcessBeforeInitialization方法完成,

public Object postProcessBeforeInitialization(Object bean, String beanName)
    throws BeansException {
    ConfigurationProperties annotation = getAnnotation(bean, beanName,
                                                       ConfigurationProperties.class);
    if (annotation != null) {
        bind(bean, beanName, annotation);
    }
    return bean;
}

它会解析@ConfigurationProperties注解上的属性,将配置文件中对应key的值绑定到属性上。

3、自动配置的生效条件

每个xxxxAutoConfiguration类上都可以定义一些生效条件,这些条件基本都是从@Conditional派生出来的。

常用的条件如下:

  • @ConditionalOnBean:当容器里有指定的bean时生效
  • @ConditionalOnMissingBean:当容器里不存在指定bean时生效
  • @ConditionalOnClass:当类路径下有指定类时生效
  • @ConditionalOnMissingClass:当类路径下不存在指定类时生效
  • @ConditionalOnProperty:指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true

举个比较常用的例子看看TransactionAutoConfiguration,是如何使用条件的

 

可以看到,条件用的是:@ConditionalOnClass,表示TransactionAutoConfiguration类只有在PlatformTransactionManager类存在时才会生效。

  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值