下面的几种方法:

注解@ComponentScan、注解@import、创建spring.factories文件、 都可以注入其他模块的bean到spring容器中。

一:SpringBoot启动类配置默认自动扫描包范围

(其他公共模块引入,使用这种方式报错bean没有注入)不知道原因

SpringBoot应用启动时,默认会自动扫描与启动类在同个包以及子包下的Bean。

所以当启动类所在的包名与项目子模块等的包名不一致时,可以在启动类上添加包扫描注解:该注解会扫描配置的包的和其子包下的bean

package com.xxx.app.bff.service;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
 
@EnableDiscoveryClient
@SpringBootApplication
@ComponentScan(value = {"com.xxx.app.bff.service.*", "com.xxx.app.bff.sdk.*"})
public class AppApplication {
    public static void main(String[] args) {
        SpringApplication.run(AppApplication.class, args);
    }
}

需要注意的是,一旦指定了@ComponentScan,则将不会在默认的启动类的包名下扫描注入容器,因此在扫描列表中还需要单独添加启动类所在的包

SpringBoot启动类自动包扫描 三种方式_风.foxwho的博客-CSDN博客_springboot指定扫描包的方式

----------------------------------------------------------------------------------------------------------------------------

二:SpringBoot 之 spring.factories理解

在springboot项目中,我们常常会在子模块中创建公共类库,那么在另一个模块中,需要加载配置文件时,往往springboot自动扫描包只能默认扫描到自己模块下的类,那我们如何解决?

springboot核心基础之spring.factories机制 - 知乎

方法一:在Spring Boot Application 主类上使用@Import注解。

关于@Import 注解有不懂的同学,建议自行学习。

方法二:创建spring.factories文件(有用)

现在我们将其改造一下,采用spring.factories 的方式去加载SwaggerConfig类,在resources目录下新建一个META-INF 的目录,然后在

新建一个spring.factories 的文件,里面的内容为:

然后在把Spring Boot 启动类上的@Import注释掉,启动发现也可以把SwaggerConfig加载到Spring 容器中:

注意:spring.factories中不能配置接口,必须是实现类

到这就完成了加载一个Spring 不能扫描到的一个类,他可以是第三方的,也可以是自己写的,只要是Spring Boot 默认扫描路径不能够扫描到,都可以使用这种方式去加载。

spring-boot包中的spring.factories文件

在Spring Boot 的很多包中都能够找到spring.factories,下面就是spring-boot 包中的spring.factories文件。

# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader


# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener


# Error Reporters
org.springframework.boot.SpringBootExceptionReporter=\
org.springframework.boot.diagnostics.FailureAnalyzers


# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer


# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener


# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor


# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer


# FailureAnalysisReporters
org.springframework.boot.diagnostics.FailureAnalysisReporter=\
org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter

在日常工作中,我们可能需要实现一些SDK 或者Sring boot starter 给别人用的时候,我们就可以使用Factories机制,Factories机制可以让SDK或者Stater的使用只需要很少或者不需要进行配置,只需要在服务中引入我们的Jar包就即可。

例如:mybatis-plus能被spring管理起来主要是项目启动类的联合注解@SpringBootApplication有一个自动装配的注解@EnableAutoConfiguration,只要有这个注解项目在启动的时候就会在引入的jar中找是否存在spring.factories的配置文件,如果找到此配置文件,将会根据此配置文件找到对应的配置类,处理jar内部需要提取的配置信息以及将需要加载到的component交给spring管理。

三、spring的拦截器中,bean注入失败问题

Bean 注入失败问题汇总-CSDN博客 --优质博客

拦截器的配置类是以new JwtInterceptor的方式使用的,那么这个JwtInterceptor不受Spring管理。因此,JwtInterceptor里边@Autowired注入JavaJwtUtil是不会注入进去的。

有问题的:

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JwtInterceptor());
    }
}

修改为:配置类中将new JwtInterceptor()改为Bean的方式


@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getJwtInterceptor());
    }
    @Bean
    JwtInterceptor getJwtInterceptor() {
        return new JwtInterceptor();
    }
}

Spring拦截器中注入Bean失败解放方案详解_java_脚本之家

@Slf4j
public class JwtInterceptor implements HandlerInterceptor {
    @Autowired
    JavaJwtUtil javaJwtUtil;
    List<String> whiteList = Arrays.asList(
            "/auth/login",
            "/error"
    );
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof Handl。。。。。。。。。。。。。。。。。。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐