Spring Boot 报WebSecurityConfigurerAdapter.class cannot be opened 原因与解决办法

本文为原创文章,欢迎转载,转载时需附上本文的原文链接

##一、问题
最近新建了一个Spring Boot应用,因为之前一直是其他同事在创建工程,没有在意Spring Boot应用创建的细节注意事项,特别是没有仔细阅读Spring Boot的官方文档。所以启动时一直报如下错误:WebSecurityConfigurerAdapter.class cannot be opened,无法启动成功,Console详细输出如下:


** WARNING ** : Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.

2018-05-29 09:47:03,458 WARN (AbstractApplicationContext.java:558)- Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [ApplicationMain]; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.class] cannot be opened because it does not exist
2018-05-29 09:47:03,490 INFO (ConditionEvaluationReportLoggingListener.java:101)- 
>
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-05-29 09:47:03,498 ERROR (SpringApplication.java:842)- Application run failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [ApplicationMain]; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.class] cannot be opened because it does not exist
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:184)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:316)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:233)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:273)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1231)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1219)
	at ApplicationMain.main(ApplicationMain.java:6)
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.class] cannot be opened because it does not exist
	at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180)
	at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:51)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103)
	at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:88)
	at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:75)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81)
	at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:734)
	at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getSuperClass(ConfigurationClassParser.java:950)
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:333)
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:194)
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:296)
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:202)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:170)
	... 13 common frames omitted

这个问题困扰了我大半天的时候,一直想不明白我的应用就是一个简单的Spring Boot web应用,并没有使用Spring Security,为什么会去加载Spring Security相关的配置,难道是Spring Boot的Web应用默认集成了Spring Security?

##二、原因分析

过程中先是大量的G狗查找,没有直接找到原因。因为一直怀疑是因spring-boot-starter-web自动依赖了Spring Security导致,所以大量查询官网资料,发现spring-boot-starter-web并没有依赖Spring Security。

后来采用了终极解决办法,按照上面的堆栈调试了一下关键的几行源码,发现Spring Boot在配置入口类的时候,自己启用了Commponent Scan。瞬间感觉柳岸花明,因为Console中一直有一个警告:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package. 起初未在意,准备最后才来解决。

后来在官网上找到这样一段话:

When a class does not include a package declaration, it is considered to be in the “default package”. The use of the “default package” is generally discouraged and should be avoided. It can cause particular problems for Spring Boot applications that use the @ComponentScan, @EntityScan, or @SpringBootApplication annotations, since every class from every jar is read.

大致意思是:当入口Class类未被包含在一个package包中的时候,将被认为包含在默认包(default package)中。Spring Boot 不鼓励并且通常应该避免不定义入口类的包名。这种情况下,Spring Boot可能会使用@ComponentScan或@EntityScan进行全局扫描,扫描每一个jar包下的每一个类。

看到这里,导致这个问题的原因已经比较明了了:应该是Spring Boot在初始化上下文中Bean的时候,进行所有包扫描,扫描到了Security相关的WebSecurityConfigurerAdapter类实例化需求,所以自动为其创建Bean实例。而事实上,由于项目并未在pom.xml中Dependency引入Spring Security相关的包或Starter,从而导致找不到class。

##三、解决

**现在解决办法就很简单了,将SpringBoot的入口类,也就是main函数或者带@SpringBootApplication的那个类,定义到一个自己命名的package中去,即这个类一定要有包名,否则就会被加到名为default的默认包名里面去。如下例所示,一定要将入口类MessengerApplication加上包名package com.brainln.framework.messenger,否则就会出现上文中的错误。

package com.brainln.framework.messenger;

@SpringBootApplication
public class MessengerApplication {

	/**
	* @Description: entrance of the application
	* @param args     
	* @throws
	*/
	public static void main(String[] args) {
		SpringApplication.run(MessengerApplication.class,args);
	}
}

注:如有更多疑问,欢迎加私友一起探讨学习,我的联系方式可在脑链网上找到

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值