springboot @Configuration 和 @Import, @EnableAutoConfiguration 注解

【参考】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
@Component
public @interface Configuration {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";

    boolean proxyBeanMethods() default true;
}

@Import

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

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {

	/**
	 * {@link Configuration @Configuration}, {@link ImportSelector},
	 * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
	 */
	Class<?>[] value();

}

示例1:@Configuration注解类

@Configuration
public 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;

@Configuration
public 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,
 * 看导入的包是不是要在本类能扫描到的路径下
 */
@SpringBootApplication
public 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
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值