SpringBoot框架(5)-- @EableAutoConfiguration项目应用
场景:在项目中想在当前maven项目中自动装配其他自定义的Maven项目,例如,创建数据库配置中心,被多个maven引用,希望简单配置,就实现springboot自动装配数据库配置类。
由此我们联想到,我们新建项目是如何装配第三方jar的?跟踪springboot源码得知,方法其实非常简单。springboot通过@EableAutoConfiguration注解,来实现这个目的。
原理:注解@EnableAutoConfiguration引用了@Import({AutoConfigurationImportSelector.class})注解,在AutoConfigurationImportSelector类中定义了getCandidateConfigurations方法加载自定义配置类。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct."); return configurations; }
由该方法提示的信息可以看到,如果自定义了需要装配的包,则需要在 META-INF/spring.factories文件中定义。如何定义呢?依葫芦画瓢,找到导入包中org/springframework/boot/spring-boot-autoconfigure/2.1.5.RELEASE/spring-boot-autoconfigure-2.1.5.RELEASE.jar!/META-INF/spring.factories文件(我当前使用的是2.1.5.版本,根据实际使用的版本不同,找到对应的方法即可)
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
看到了 Auto Configure,这就我们需要配置的内容,在我们需要的导入到当前maven项目的文件resources\META-INF\spring.factories中添加需要装配的配置类的全路径,如下
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.boot.config.core.config.BeanConfiguration #需要装配的配置类的全路径
至此,在当前项目块的配置类实例。
原理至此,上代码
准备两个需要被引用的maven项目
第一个项目bean-core,代码结构
(1)在domain中定义了2个bean类--Order和Product,没有属性和方法,也不用添加注解。再新建BeanConfiguration配置类如下
1 package com.boot.config.core.config; 2 3 import com.boot.config.core.domain.Order; 4 import com.boot.config.core.domain.Product; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Configuration; 7 8 @Configuration 9 public class BeanConfiguration { 10 11 @Bean 12 public Order creatOrder() { 13 return new Order(); 14 } 15 16 @Bean 17 public Product createProduct() { 18 return new Product(); 19 } 20 }
(2)在spring.factories文件中添加以下内容
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.boot.config.core.config.BeanConfiguration #BeanConfiguration类全路径
同理在confing-core项目中,做相同的处理。
第二个项目
(1)定义数据源bean类
1 package com.boot.config.core; 2 3 /** 4 * 数据源属性类 5 * 6 */ 7 public class DatasourceProperties 8 { 9 private String driverClassName; 10 private String url; 11 private String userName; 12 private String password; 13 14 public String getDriverClassName() { 15 return driverClassName; 16 } 17 18 public void setDriverClassName(String driverClassName) { 19 this.driverClassName = driverClassName; 20 } 21 22 public String getUrl() { 23 return url; 24 } 25 26 public void setUrl(String url) { 27 this.url = url; 28 } 29 30 public String getUserName() { 31 return userName; 32 } 33 34 public void setUserName(String userName) { 35 this.userName = userName; 36 } 37 38 public String getPassword() { 39 return password; 40 } 41 42 public void setPassword(String password) { 43 this.password = password; 44 } 45 }
(2)定义数据源配置类
1 package com.boot.config.core; 2 3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Configuration; 6 7 @Configuration 8 public class DatasourceConfig { 9 10 @Bean 11 @ConfigurationProperties(prefix = "jdbc") 12 public DatasourceProperties createDatasourceProperties() { 13 return new DatasourceProperties(); 14 } 15 }
(3)配置资源文件spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.boot.config.core.DatasourceConfig
第三个项目,引用了 第一、二项目
(1)pom.xml文件中引用第三方jar包依赖
<dependency> <groupId>com.boot.config.core</groupId> <artifactId>bean-core</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.boot.config.core</groupId> <artifactId>config-core</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
(2)application.properties文件中设置数据源配置
jdbc.driverClassName=com.mySql.jdbc.mySqlDriver
jdbc.userName=root
jdbc.password=root.123
jdbc.className=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/bookstore
(3)main方法中打印第三方配置信息
1 package com.boot.auto.bootauto; 2 3 import com.boot.config.core.DatasourceProperties; 4 import com.boot.config.core.config.BeanConfiguration; 5 import com.boot.config.core.domain.Order; 6 import com.boot.config.core.domain.Product; 7 import org.springframework.boot.SpringApplication; 8 import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 9 import org.springframework.context.ConfigurableApplicationContext; 10 import org.springframework.context.annotation.ComponentScan; 11 12 //设置不装配的配置类 13 //@EnableAutoConfiguration(exclude= {BeanConfiguration.class}) 14 @EnableAutoConfiguration 15 @ComponentScan 16 public class BootAutoApplication { 17 18 public static void main(String[] args) { 19 ConfigurableApplicationContext context = SpringApplication.run(BootAutoApplication.class, args); 20 System.out.println(context.getBean(Order.class)); 21 System.out.println(context.getBean(Product.class)); 22 23 DatasourceProperties jdbcBean = context.getBean(DatasourceProperties.class); 24 25 System.out.println(jdbcBean.getDriverClassName()); 26 System.out.println(jdbcBean.getUrl()); 27 System.out.println(jdbcBean.getUserName()); 28 System.out.println(jdbcBean.getPassword()); 29 30 context.close(); 31 } 32 33 }
(4)打印结果
com.boot.config.core.domain.Order@3a71c100 com.boot.config.core.domain.Product@5b69fd74 com.mySql.jdbc.mySqlDriver jdbc:mysql://localhost:3306/bookstore root root.123
由此可以看到我们在其他(第三方)的配置类成功装配到我们当前项目中来。
总结
1、被引用的第三方maven项目(A)中定义了配置类
2、在A项目的META_INFO/spring.properties文件中添加需要装配的配置类的全路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.boot.config.core.config.BeanConfiguration
3、引用项目(B)在pom.xml中添加对A的jar引用
4、使用@EnableAutoConfiguration,从而在ConfigurableApplicationContext的实例对A项目的配置进行访问操作。