博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springboot @Configuration 和 @Import, @EnableAutoConfiguration 注解
阅读量:4296 次
发布时间:2019-05-27

本文共 4718 字,大约阅读时间需要 15 分钟。

【参考】https://blog.csdn.net/Janson_Lin/article/details/87778878

https://blog.csdn.net/qq_36872046/article/details/83662761
https://www.cnblogs.com/hermanlife/p/10019473.html

@Configuration

一般用来声明配置类,可以使用 @Component注解替代,不过使用Configuration注解声明配置类更加语义化。

@Target({
ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Configuration {
@AliasFor( annotation = Component.class ) String value() default ""; boolean proxyBeanMethods() default true;}

@Import

用法:1.导入配置类, 2.导入普通类(4.2之前只支持导入配置类)

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Import {
/** * {@link Configuration @Configuration}, {@link ImportSelector}, * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import. */ Class
[] value();}

示例1:@Configuration注解类

@Configurationpublic class MoonBookConfiguration {
@Bean public BookService bookService() {
return new BookServiceImpl(); }}@Configuration// 可以同时导入多个配置类,比如:@Import({A.class,B.class})@Import(MoonBookConfiguration.class)public class MoonUserConfiguration {
@Bean public UserService userService(BookService bookService) {
return new UserServiceImpl(bookService); }}

示例2:普通类

public class BookServiceImpl implements BookService {
public BookServiceImpl() {
System.out.println("实例化BookService."); } }@Configuration// 可以同时导入多个配置类,比如:@Import({A.class,B.class}@Import(BookServiceImpl.class)public class MoonUserConfiguration {
public MoonUserConfiguration() {
System.out.println("实例化MoonUserConfiguration"); } @Bean public UserService userService(BookService bookService) {
return new UserServiceImpl(bookService); }}

import注解生效机制

Springboot对注解的处理都发生在AbstractApplicationContext -> refresh() -> invokeBeanFactoryPostProcessors(beanFactory) -> ConfigurationClassPostProcessor -> postProcessBeanDefinitionRegistry()方法中。

在这里插入图片描述
在 ConfigurationClassParser -> processConfigurationClass() -> doProcessConfigurationClass() 方法中我们找到了@Component, @PropertySource, @ComponentScan, @Import, @ImportResource的处理.

// Process any @Import annotations		processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

import处理流程:

  • 首先, 判断如果被import的是 ImportSelector.class 接口的实现, 那么初始化这个被Import的类, 然后调用它的selectImports方法去获得所需要的引入的configuration, 然后递归处理
  • 其次, 判断如果被import的是 ImportBeanDefinitionRegistrar 接口的实现, 那么初始化后将对当前对象的处理委托给这个ImportBeanDefinitionRegistrar (不是特别明白, 只是我的猜测)
  • 最后, 将import引入的类作为一个正常的类来处理 ( 调用最外层的doProcessConfigurationClass())
    所以, 从这里我们知道, 如果你引入的是一个正常的component, 那么会作为@Compoent或者@Configuration来处理, 这样在BeanFactory里边可以通过getBean拿到, 但如果你是 ImportSelector 或者 ImportBeanDefinitionRegistrar 接口的实现, 那么spring并不会将他们注册到beanFactory中,而只是调用他们的方法。

@EnableAutoConfiguration

@EnableAutoConfiguration注解表示开启Spring Boot自动配置功能,Spring Boot会根据应用的依赖、自定义的bean、classpath下有没有某个类 等等因素来猜测你需要的bean,然后注册到IOC容器中。

那 @EnableAutoConfiguration是如何推算出你的需求?看@Import(EnableAutoConfigurationImportSelector.class).
@Import注解用于导入类,并将这个类作为一个bean的定义注册到容器中,这里它将把 EnableAutoConfigurationImportSelector作为bean注入到容器中,而这个类会扫描所有的jar包,将所有符合条件的@EnableAutoConfiguration配置都加载到容器中:

// 来自 org.springframework.boot.autoconfigure下的META-INF/spring.factories// 配置的key = EnableAutoConfiguration,与代码中一致org.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration\.....

开启了这个注解,也就意味这springboot 帮你集成了大批的热门,火热的开源技术,不再需要你导入集成配置.

另外一个作用,就是如果有自定义的类,并不是在当前启动类的扫描路径下,也可以通过这种方式被扫进来被容器管理.
比如:
在这里插入图片描述

package com.one.bean.auto.configuration;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyEnableAutoConfiguration {
public MyEnableAutoConfiguration() {
System.out.println("实例化MyEnableAutoConfiguration."); }}package com.one.bean.spring.boot.autoconfiguration;import com.one.bean.auto.configuration.MyEnableAutoConfiguration;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;/** * 用来测试@AutoEnableConfiguration, * 看导入的包是不是要在本类能扫描到的路径下 */@SpringBootApplicationpublic class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class); MyEnableAutoConfiguration bean = context.getBean(MyEnableAutoConfiguration.class); context.close(); }}

并在spring.factories里配置:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.one.bean.auto.configuration.MyEnableAutoConfiguration
你可能感兴趣的文章
open,write,read函数
查看>>
TFTP服务器搭建
查看>>
搭建NFS服务器
查看>>
linux延时函数
查看>>
man命令的使用
查看>>
stat函数组
查看>>
chmod权限
查看>>
getcwd()获取当前目录
查看>>
mkdir创建目录
查看>>
chdir改变当前目录
查看>>
opendir 、closedir 、readdir 目录函数
查看>>
硬链接link、符号链接symlink、解除链接unlink
查看>>
拷贝文件
查看>>
移动函数rename
查看>>
进程标识符
查看>>
进程操作
查看>>
exec()函数
查看>>
进程通信之无名管道
查看>>
进程通信之有名管道
查看>>
进程通信之消息队列
查看>>