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可以放置在任何模块中,可以是引入者或被引入者

posted @ 2019-11-18 22:53  雷雨客  阅读(1215)  评论(0编辑  收藏  举报