Springboot - 自动装配 - 自定义Spring-Boot @EnableXXX注解

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;
  }
}

然后写一个启动注解

扫描二维码关注公众号,回复: 8987592 查看本文章
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, 具体的细节,等有时间了在写

发布了442 篇原创文章 · 获赞 1375 · 访问量 210万+

猜你喜欢

转载自blog.csdn.net/qq_15071263/article/details/103242518