Springboot自动配置

本文主要探讨了Springboot源码中的常用注解,包括@Value、@ConfigurationProperties、@EnableConfigurationProperties、@Import和@Conditional。@Value用于简单属性注入,@ConfigurationProperties则将配置文件中的属性与类绑定。@EnableConfigurationProperties使得未使用@Component的配置属性类也能被加载。@Import允许导入Java类作为Bean,@Conditional根据特定条件启用配置。最后,@SpringBootApplication是Springboot应用的启动入口,包含自动配置功能。

1. Springboot源码常用注解

注解分类:

  • 元注解:可以注解到别的注解上的注解。
  • 组合注解:被注解的注解我们就称之为组合注解。当多个注解被标注在同一个类上时,可以将这多个注解合并成一个注解。这个被合并的注解就是组合注解,如@SpringBootApplication
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration// 自动配置注解
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {// SpringBootApplication是一个组合注解
    @AliasFor(
        annotation = EnableAutoConfiguration.class,
        attribute = "exclude"
    )
    Class<?>[] exclude() default {};

    @AliasFor(
        annotation = EnableAutoConfiguration.class,
        attribute = "excludeName"
    )

1.1 @Value 【Spring 提供】

@Value 就相当于传统 xml 配置文件中的 value 字段。

<bean class="RequestTestRunnerService"> 
<property name ="APP_ENV" value="pre"></property>
</bean> 

@Value取值来源: 

  • 字面量 @Value("值")
  • 通过 ${key} 方式从环境变量中获取值
  • 通过 ${key} 方式全局配置文件 application.yml中获取值
  • #{SpEL}
@Slf4j
@Service("requestTestRunnerService")
public class RequestTestRunnerService {


    public static String APP_ENV;

    @Value("${appEnv}")
    private void setAppEnv(String appEnv) {
        // static 变量只能通过set方法注入值
        APP_ENV = appEnv;
    }
}

1.2 @ConfigurationProperties 【Springboot】

@Value 的升级版,@ConfigurationProperties将标注的类中的属性和配置文件中的配置项绑定起来。默认配置文件是主配置文件application.yml

// 线程池配置项
task:
  pool:
    corePoolSize: 20
    maxPoolSize: 40
    keepAliveSeconds: 300
    queueCapacity: 50
    threadNamePrefix: nanaThread-
// 如下是@ConfigurationProperties标注的配置项类,类中属性与配置文件中的配置项一一绑定,
// 类中属性名和配置文件中的属性名必须相同,且配置项类必须有setter和getter方法,否则无法注入成功。

@Data
@ConfigurationProperties(prefix = "task.pool")
public class ThreadPoolProperties {
    private int corePoolSize;

    private int maxPoolSize;

    private int keepAliveSeconds;

    private int queueCapacity;

    private String threadNamePrefix;

}

注:

如果一个配置类只配置@ConfigurationProperties注解,而没有使用@Component,那么在IOC容器中是获取不到properties 配置文件转化的bean,即获取不到ThreadPoolProperties。

 

1.2.1 @EnableConfigurationProperties 【Springboot】

@EnableConfigurationProperties可以解决上述,没有使用配置属性类@Component时,获取不到ThreadPoolProperties 的bean的问题。

@EnableConfigurationProperties注解应用到你的@Configuration时, 任何被@ConfigurationProperties注解的beans将自动被Environment属性配置。 这种风格的配置特别适合与SpringApplication的外部YAML配置进行配合使用。如下所示:

// 线程池配置类
@Slf4j
@Configuration
@EnableConfigurationProperties({ThreadPoolProperties.class})
@EnableAsync
public class ThreadPoolAutoConfiguration {

    private static final int THREADS = Runtime.getRuntime().availableProcessors() + 1;

    @Autowired
    private ThreadPoolProperties threadPoolProperties;

    /**
     * 异步任务执行器
     * @return
     */
    @Bean
    public Executor asyncServiceExecutor() {
        log.info("start asyncServiceExecutor");
        ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(THREADS);
        //配置最大线程数
        executor.setMaxPoolSize(threadPoolProperties.getMaxPoolSize());
        //配置队列大小
        executor.setQueueCapacity(99999);
        //配置线程池中的线程的名称前缀
//        executor.setThreadNamePrefix("AsyncService-");
        executor.setThreadNamePrefix(threadPoolProperties.getThreadNamePrefix());

        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }

}

 

1.3 @Import 【Spring 提供】

@Import 注解支持导入普通 java 类,并将其声明成一个bean。主要用于将多个分散的 java config 配置类融合成一个更大的 config 类。

 

(1)导入普通的java类

// 普通java类
public class Circle { 

public void sayHi() { 
System.out.println("Circle sayHi()"); 
} 

} 

// 导入java类,成为IOC容器中的bean
@Import({Circle.class}) 
@Configuration 
public class MainConfig { 

} 

public static void main(String[] args) { 

ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); 
Circle circle = context.getBean(Circle.class); 
circle.sayHi(); 

} 

(2)配合自定义的 ImportSelector 使用

ImportSelector 是一个接口,该接口中只有一个 selectImports 方法,用于返回全类名数组。所以利用该特性我们可以给容器动态导入 N 个 Bean。

public class Triangle { 

public void sayHi(){ 
System.out.println("Triangle sayHi()"); 
} 

}

public class MyImportSelector implements ImportSelector { 

@Override 
public String[] selectImports(AnnotationMetadata annotationMetadata) { 
    // 返回的是全路径类名
return new String[]{"annotation.importannotation.waytwo.Triangle"}; 
} 

} 
// 导入类
@Import({Circle.class,MyImportSelector.class}) 
@Configuration 
public class MainConfigTwo { 

} 

 

1.4 @Conditional 【Spring提供】

 

@Conditional 注解:只有在特定条件满足时才启用配置。

Spring 还为我们扩展了一些常用的 Condition。

 

扩展注解 作用

ConditionalOnBean 容器中存在指定 Bean,则生效。

ConditionalOnMissingBean 容器中不存在指定 Bean,则生效。

ConditionalOnClass 系统中有指定的类,则生效。

ConditionalOnMissingClass 系统中没有指定的类,则生效。

ConditionalOnProperty 系统中指定的属性是否有指定的值。

ConditionalOnWebApplication 当前是web环境,则生效。

 

1.5 @SpringBootApplication 【Springboot】

springboot应用通过注解@SpringBootApplication标注的类是应用启动的入口,是应用的主类。

而@SpringBootApplication注解定义中包含自动配置注解@EnableAutoConfiguration

 

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration// 自动配置注解
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    @AliasFor(
        annotation = EnableAutoConfiguration.class,
        attribute = "exclude"
    )
    Class<?>[] exclude() default {};

    @AliasFor(
        annotation = EnableAutoConfiguration.class,
        attribute = "excludeName"
    )

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值