Spring Boot 之 spring.factories
引言
在 java spring cloud 项目中,我们常常会在子模块中创建公共类库,作为驱动包。那么在另外一个子模块中,需要加载配置文件的时候,往往 Spring Boot 自动扫描包的时候,只会扫描自己模块下的类。
抛出一个问题
首先抛出一个问题:如果想要被Spring容器管理的Bean的路径不再Spring Boot 的包扫描路径下,怎么办呢?也就是如何去加载第三方的Bean 呢?
有两种方式可以解决:
这里我们使用 Swagger 的配置来做实验。
1:首先一个 Swagger 的配置类:SwaggerConfig
SwaggerConfig 代码:
@Configuration
@EnableSwagger2
public class SwaggerConfig implements EnvironmentAware {
private static final Logger log = LoggerFactory.getLogger(SwaggerConfig.class);
@Autowired
private Environment env;
@Value("${swagger.scan.package}")
private String swaggerScanPackage;
public SwaggerConfig() { }
@Bean
public Docket createRestApi() {
Predicate<String> path = PathSelectors.any();
if (Arrays.asList(this.env.getActiveProfiles()).contains("prod")) {
path = PathSelectors.none();
}
log.info("#### 初始化 createRestApi####swaggerScanPackage:" + this.swaggerScanPackage);
log.info(path.toString());
return (new Docket(DocumentationType.SWAGGER_2)).apiInfo(this.apiInfo()).select().apis(RequestHandlerSelectors.basePackage(this.swaggerScanPackage)).paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo() {
log.info("################################## 初始化 API 信息 ################################################");
return (new ApiInfoBuilder()).title("APIs").description("…………").termsOfServiceUrl("https://js.dazhi.loan.com").version("1.0").build();
}
@Override
public void setEnvironment(Environment environment) {}}
2:再看我的工程结构吧:
发现我的 SwaggerConfig 类和 SpringBoot 的启动类 ConfigApplication.java 不在同一级目录下,所以当 Spring Boot 自动扫描包的时候,是扫描不到我的 SwaggerConfig 的配置的,也就在控制台没有 Swagger 的打印的信息:
所以这时候我如果想要把 SwaggerConfig 加载到 Spring 容器中的话 要怎么办呢?下面介绍两种方式
方法一、在 Spring Boot Application 主类上 使用 @Import 注解
方法二、创建 spring.factories 文件
现在我们将其改造一下,采用 spring.factories 的方式去加载 SwaggerConfig 类,在 resources 目录下新建一个 META-INF 的目录,然后在
新建一个 spring.factories 的文件,里面的内容为:
1 2 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.sg.config.SwaggerConfig |
然后在把 Spring Boot 启动类上的 @Import 注释掉,启动发现也可以把 SwaggerConfig 加载到 Spring 容器中
到这就完成了加载一个 Spring 不能扫描到的一个类,他可以是第三方的,也可以是自己写的,只要是 Spring Boot 默认扫描路径不能够扫描到,都可以使用这种方式去加载!!!