SpringBoot使用EnableAutoConfiguration与spring.factories装配其它模块的bean
Spring Boot使用EnableAutoConfiguration和spring.factories解决了在一个模块中把其它模块的类装配成bean的问题
一、怎样实现
1、配置文件中enableautoconfiguration设置为true(默认为true)
2、引入其它模块的依赖
3、在其它模块的resources/META-INF/spring.factories中配置需要装载的类全名
二、代码演示
1、新建普通工程core-bean
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.8.RELEASE</version> </dependency>
public class Role {} public class User {} @Configuration public class UserConfiguration { @Bean public User createUser(){ return new User(); } } @Configuration public class RunnableConfiguration { @Bean public Runnable createRunnable(){ return ()->{}; } }
2、在core-bean中新建resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.leiyuke.core.bean.RunnableConfiguration,\
com.leiyuke.core.bean.UserConfiguration,\
com.leiyuke.core.bean.Role
3、新建Spring Boot工程core-bean-app,并引入core-bean的依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.leiyuke</groupId> <artifactId>core-bean</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
4、新建启动类测试,可以输出bean
@SpringBootApplication public class App { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(App.class,args); User user = context.getBean(User.class); System.out.println(user); Role role = context.getBean(Role.class); System.out.println(role); Runnable runnable = context.getBean(Runnable.class); System.out.println(runnable); UserConfiguration userConfiguration = context.getBean(UserConfiguration.class); System.out.println(userConfiguration); RunnableConfiguration runnableConfiguration = context.getBean(RunnableConfiguration.class); System.out.println(runnableConfiguration); } }
三、其它情况
怎样排除不装配其它模块的指定类
假如不装配UserConfiguration和User,可以使用下面的方式启动
@ComponentScan @EnableAutoConfiguration(exclude = UserConfiguration.class) public class App { ... ... }
假如不装配UserConfiguration、User、Role,可以使用下面两种方式启动
@ComponentScan @EnableAutoConfiguration(exclude = {UserConfiguration.class,Role.class}) public class App { ... ... } @ComponentScan @EnableAutoConfiguration(excludeName = {"com.leiyuke.core.bean.UserConfiguration","com.leiyuke.core.bean.Role"}) public class App { ... ... }
四、spring.factories是如何起作用的
源码很简单,大体情况如下,读不懂源码的可以看一下我的这篇记录
1)SpringBootApplication注解包了EnableAutoConfiguration注解
2)EnableAutoConfiguration注解中定义了spring.boot.enableautoconfiguration配置参数
3)EnableAutoConfiguration注解的Import类中先判断enableautoconfiguration是否设置为true
4)然后解析配置文件spring.factories,去掉配置重复的,移除掉排除的(exclude)
5)最终将spring.factories中所有的类名存在一个数组中,提供给selectImports方法作为返回值
五、总结
1)EnableAutoConfiguration 从classpath中搜索所有spring.factories文件,将其中的配置项装配成bean,加载到spring容器
2)application.properties中,spring.boot.enableautoconfiguration=true 时才生效,默认true
3)可以使用exclude或者excludeName根据类型或者类名排除不需要的bean
注意:spring.factories可以放置在任何模块中,可以是引入者或被引入者