文章目录
Springboot - 自动装配 - 自定义Spring-Boot @EnableXXX注解
1、从springboot 自带的@EnableXX注解出发
spring boot 自带了很多@EnableXXX
这样的注解,通过这些注解我们可以很方便地启用某些功能
比如@EnableAutoConfiguration
用来开启自动装配的功能。
2、内部主要实现原理 @Import
他的运行机制,是通过 @Import
注解将制定的类注入Spring IOC 容器中,成为一个bean
比如 @EnableAutoConfiguration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
3、@Import
的几种介入方式
1、直接把某个配置类注册引入
2、引入一个ImportSelector
的实现类
3、引入一个ImportBeanDefinitionRegistrar
的实现类
4、直接把某个配置类注册引入
以druid 数据源配置为例,先写好配置类,但是不打@Configuration
注解
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.google.common.collect.Maps;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.util.Map;
@Data
@ConfigurationProperties(prefix = "spring.datasource.druid")
public class DruidConfiguration {
private String jdbcUrl;
private String username;
private String password;
private String validationQuery;
private String driverClassName;
private Integer initialSize;
private Integer maxActive;
private Integer minIdle;
private Integer maxWait;
private Integer maxOpenPreparedStatements;
private Boolean poolPreparedStatements;
private Boolean testOnBorrow;
private Boolean testOnReturn;
private Boolean testWhileIdle;
@Bean
public ServletRegistrationBean indexServletRegistration() {
ServletRegistrationBean<StatViewServlet> registration =
new ServletRegistrationBean<>(new StatViewServlet());
registration.addUrlMappings("/druid/*");
registration.addInitParameter("loginUsername", "admin");
registration.addInitParameter("loginPassword", "admin");
return registration;
}
@Bean
public FilterRegistrationBean indexFilterRegistration() {
FilterRegistrationBean<WebStatFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new WebStatFilter());
registration.addUrlPatterns("/*");
Map<String, String> map = Maps.newHashMap();
map.put("exclusions", "*.ico,/druid/*,/static/*");
registration.setInitParameters(map);
return registration;
}
@Bean
@Primary
public DataSource dataSource() {
DruidDataSource db = new DruidDataSource();
db.setUrl(jdbcUrl);
db.setUsername(username);
db.setPassword(password);
db.setValidationQuery(validationQuery);
db.setDriverClassName(driverClassName);
db.setInitialSize(initialSize);
db.setMaxActive(maxActive);
db.setMinIdle(minIdle);
db.setMaxWait(maxWait);
db.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
db.setPoolPreparedStatements(poolPreparedStatements);
db.setTestOnBorrow(testOnBorrow);
db.setTestOnReturn(testOnReturn);
db.setTestWhileIdle(testWhileIdle);
return db;
}
}
然后写一个启动注解
import com.web.framework.data.DruidConfiguration;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* @author Created by 谭健 on 2019/11/15. 星期五. 13:53.
* © All Rights Reserved.
* <p>
* druid 数据源的启动器
*/
@Import(DruidConfiguration.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface EnableDruidDataSource {
}
这样,吧@EnableDruidDataSource
注解写在某个spring 的组件上,就可以让spring 加载druid 的配置了,如果不加该注解,则不会加载druid 数据源
5、引入一个ImportSelector
的实现类
用户通过实现 ImportSelector
接口,然后 import ImportSelector
接口实现类来注入的方式让用户能够更加灵活的启动进行配置,让用户在注入之前,可以做一些事情,或者根据指定的条件,加载不同的组件
6、引入一个ImportBeanDefinitionRegistrar
的实现类
用户通过实现 ImportBeanDefinitionRegistrar
接口,然后 import ImportBeanDefinitionRegistrar
接口实现类来注入的方式让用户能够更加灵活的启动进行配置,让用户在注入之前,可以做一些事情,或者根据指定的条件,加载不同的组件
ImportSelector
, ImportBeanDefinitionRegistrar
, 具体的细节,等有时间了在写