本文共 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一般用来声明配置类,可以使用 @Component注解替代,不过使用Configuration注解声明配置类更加语义化。
@Target({ ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Configuration { @AliasFor( annotation = Component.class ) String value() default ""; boolean proxyBeanMethods() default true;}
用法: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); }}
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处理流程:
@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