背景
这是我在学习SpringSecurity组件时出现的一个问题。大致情况就是
我有两个工程:
security-demo
这是一个springboot工程security-browser
这是一个spring工程,用于作为Jar包给security-demo工程使用
配置情况:
security-browser
工程中有个config配置类
//这是一个Spring Java配置类 @Configuration public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter { ``` //内容不重要,总之内部需要实现某些功能 }
security-demo
的pom中依赖了security-browser
的jar包
<dependency> <groupId>com.snailmann.security</groupId> <artifactId>security-browser</artifactId> <version>${project.version}</version> </dependency>
期望:
我的期望是当我启动security-demo
项目,security-browser
中的BrowserSecurityConfig
类会被注入到Spring容器中,完成某些功能。
问题:
问题就是BrowserSecurityConfig
类并没有被security-demo
项目的Spring容器实例化,因为Spring容器中并没有BrowserSecurityConfig
,所以导致我要在BrowserSecurityConfig
实现的某些功能失效
分析
security-browser
工程是否没有正确打包security-demo
并没有引入security-browser
的jar包- Configuration配置错误
- Spring不支持扫描Jar包组件
- 是否少配置了什么东西?
- etc…
解决方案
经过实践,大部分的问题都被排除掉了,几个小时也过去了。最后面,某些资料引起了我的注意。大致就是有人遇到了SpringBoot工程无法扫描Jar包中组件的问题,So…
How to make Spring’s @ComponentScan search components in included JARs
方法一
因为Jar包中的Configuration类没有被注入,所以我们可以在Demo项目中手工注入,通过在demo模块中的Configuration类中声明
@Bean public BrowserSecurityConfig getBrowserSecurityConfig(){ return new BrowserSecurityConfig(); }
虽然这样可以实现,但这种方式并不好,相当于声明了两次
方法二
另一种方式就从@ComponentScan注解下手,但因为对这个注解的理解还不够深入,所以暂且得出这一个简略的方法
@ComponentScan(basePackages={"com.snailmann.security.demo","com.snailmann.security.browser"}) @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
因为在SpringBoot的默认扫描中,貌似是不会扫描Jar包中的组件,所以我们得显示的声明Spring容器要扫描的路径。这就包括了本项目的路径,以及要扫描的Jar包的路径。com.snailmann.security.demo是demo项目的路径,com.snailmann.security.browser是Jar包的路径
当然我们可以看到的是如果两个项目的主路径几乎相同,我们可以简写成
@ComponentScan(basePackages={"com.snailmann.security"}) @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }