自动装配
传统 Spring 整合其他的包的步骤
- 读取配置文件
- 装配Bean的Config
- 导入主配置类
SpringBoot 整合其他的包的步骤
这会发现一个问题,如果每一次创建 Spring 项目都需要写配置类,会导致效率下降。
而配置类大部分都是固定的创建Bean的流程,无非就是具体配置不同而已。
SpringBoot 提供的基于 SPI 完成的自动配置可以解决这个问题
- 读取配置可以通过 SpringBoot 提供 @ConfigurationProperties 注解完成读取,读取的配置存放到 XXXProperties 中
- 将 XXXProperties 注入到 XXXAutoConfig,通过注入的Properties类完成创建 Bean 的流程
- 通过 spring.factories 配置文件注入到 SpringBoot 的自动配置类中
Application启动类介绍
Application启动类,同时也是配置类
上面的复合注解 @SpringBootApplication
表示一个configuration类,声明一个或多个@Bean方法,同时触发auto-configuration和component scanning 。这是一个方便的注释,相当于声明@SpringBootConfiguration 、 @EnableAutoConfiguration和@ComponentScan 。
自动配置类介绍
为什么不需要用于整合的配置类,因为SpringBoot有自动配置类
现在不需要装配一些常见的配置类,因为常见的依赖都有自动配置的包,比如mybatis-spring-boot-starter依赖了mybatis-spring-boot-autoconfigure
而Application启动类上的注解 @SpringBootApplication 触发了自动装配的操作
@SpringBootApplication
@SpringBootApplication中有
@SpringBootConfiguration 声明配置类
@EnableAutoConfiguration 启用自动配置的关键,它导入了一个AutoConfigurationImportSelectord的自动配置选择器,在这个选择器中利用SpringFactoriesLoader(框架内部使用的通用工厂装载机制)读取了META-INF/spring.factories
的文件
@EnableAutoConfiguration里面有@Import(AutoConfigurationImportSelector.class) 导入了类自动配置导入选择器
SpringBoot整合案例
C3p0DataSourceProperties.java
@Data
/**
* 将yml配置的属性绑定到这个类中 使用松散绑定
* 外部化配置的注释。如果您想绑定和验证一些外部属性(例如,从.Properties文件),请将其添加到类定义或@Configuration类中的@Bean方法中。
* 绑定可以通过调用带注释类上的setter来执行,也可以通过绑定到构造函数参数来执行,如果@ConstructorBinding正在使用中。
* 请注意,与@Value相反,由于属性值是外部化的,因此不会计算SpEL表达式。
*/
@ConfigurationProperties(prefix = "spring.datasource.c3p0")
public class C3p0DataSourceProperties {
// 驱动类名
private String driverClassName;
// 数据库连接地址
private String url;
// 用户名
private String userName;
// 密码
private String password;
// 最小连接池大小
private Integer minPoolSize;
// 最大连接池大小
private Integer maxPoolSize;
// 初始连接池大小
private Integer initialPoolSize;
// 最大空闲时间
private Integer maxIdleTime;
}
C3p0DataSourceAutoConfigure.java
@Configuration
//@ConditionalXxx的都是spring提供的条件注解,这些注解的作用
//就是当满足某个条件的时候才会执行装配
//例如@ConditionalOnClass,它表示当classpath中存在
//ComboPooledDataSource(C3P0核心连接池)这个类的时候
//才会初始化当前的配置类
@ConditionalOnClass(ComboPooledDataSource.class)
//这个注解表示当前的配置类在DataSourceAutoConfiguration之前
//加载并初始化
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
//将带有@ConfigurationProperties注解的类纳入Spring的IOC容器中
//以便于在任何地方可以进行注入
@EnableConfigurationProperties(C3p0DataSourceProperties.class)
public class C3p0DataSourceAutoConfigure {
/**
* 注入CP30的配置属性
*/
private C3p0DataSourceProperties properties;
@Autowired
public void setProperties(C3p0DataSourceProperties properties) {
this.properties = properties;
}
@Bean
//这个条件注解标识当容器中存在这个Bean的时候才会执行装配
//@ConditionalOnBean
//这个条件注解标识当容器中不存在这个Bean的时候才会执行装配
@ConditionalOnMissingBean
public DataSource dataSource() throws PropertyVetoException {
//创建C3P0的数据源
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//将配置属性设置到dataSource中
dataSource.setDriverClass(properties.getDriverClassName());
dataSource.setJdbcUrl(properties.getUrl());
dataSource.setUser(properties.getUserName());
dataSource.setPassword(properties.getPassword());
dataSource.setMinPoolSize(properties.getMinPoolSize());
dataSource.setMaxPoolSize(properties.getMaxPoolSize());
dataSource.setInitialPoolSize(properties.getInitialPoolSize());
dataSource.setMaxIdleTime(properties.getMaxIdleTime());
return dataSource;
}
}
spring.factories
# 启用Spring应用程序上下文的自动配置,尝试猜测和配置您可能需要的bean
org.springframework.boot.autoconfigure.EnableAutoConfiguration = \
org.c3p0.spring.boot.autoconfigure.C3p0DataSourceAutoConfigure