出现问题的项目算是一个新项目,但基本的脚手架代码是从另一个项目里迁过来的,原项目并没有报错,只有新项目才报异常。看报错内容,判断发生冲突的主要是spring-boot-starter-security和springfox-swagger2这两个jar包的文件。

  新项目错误如下:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
15:22:32.350 spotcheck-system [main] ERROR o.s.b.d.LoggingFailureAnalysisReporter - ***************************
APPLICATION FAILED TO START
*************************** Description: Method springSecurityFilterChain in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration required a single bean, but 2 were found:
- requestMappingHandlerMapping: defined by method 'requestMappingHandlerMapping' in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]
- swagger2ControllerMapping: defined by method 'swagger2ControllerMapping' in class path resource [springfox/documentation/swagger2/configuration/Swagger2DocumentationConfiguration.class] Action: Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping' available: expected single matching bean but found 2: requestMappingHandlerMapping,swagger2ControllerMapping

  我的项目中出错代码是这一行,在原项目并没有报错。

Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = applicationContext.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();

  getBean方法默认是byType来加载bean对象的,如果取到相同类型的2个就会报错。我分别查看了错误中提示的DelegatingWebMvcConfiguration.class和Swagger2DocumentationConfiguration.class。

  1. DelegatingWebMvcConfiguration.class里并没有requestMappingHandlerMapping方法,DelegatingWebMvcConfiguration继承了WebMvcConfigurationSupport.class类,在WebMvcConfigurationSupport.class类中有requestMappingHandlerMapping方法,返回值是RequestMappingHandlerMapping.class。代码如下:

    /**
* Return a {@link RequestMappingHandlerMapping} ordered at 0 for mapping
* requests to annotated controllers.
*/
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
......
}

  2. Swagger2DocumentationConfiguration.class里有swagger2ControllerMapping方法如下:

  @Bean
public HandlerMapping swagger2ControllerMapping(
Environment environment,
DocumentationCache documentationCache,
ServiceModelToSwagger2Mapper mapper,
JsonSerializer jsonSerializer) {
return new PropertySourcedRequestMappingHandlerMapping(environment, new Swagger2Controller(environment, documentationCache, mapper, jsonSerializer));
}

  这个方法里的返回值类型PropertySourcedRequestMappingHandlerMapping继承了RequestMappingHandlerMapping类,

public class PropertySourcedRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
......
}

  所以可能Spring加载时,根据byType形式会认错了吧。

  解决办法:既然Spring加载时使用byType形式会报错,那我们就用byName形式加载。Spring中使用@Bean声明的方法,如果没有指定名称,默认的name就是方法名。所以我们把出错代码改成:

        RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();

  到此问题解决。

补充一下:

  假设自己项目中有一个接口,同时有两个实现类,并且实现类都使用了@Service注解,你在使用过程中使用了@Autowired注解进行引用。这时Spring初始化时就会报错:expected single matching bean but found 2 ,因为@Autowired默认是byType形式加载的。

  解决办法就是用@Primary、@Qualifier这两个注解来解决问题。

  @Primary注解是用来声明2个实现类那个是主要的。与@Component、@Service等注解放到一起使用。这时Spring通过@Autowired加载时,就会判断一下, 优先使用@Primary注解的类。

  @Qualifier显示声明加载类的名称,与@Autowired放到一起使用,这样Spring加载时判断类型相同,会在通过名称筛选出需要的类,就不会报错了。其实@Autowired + @Qualifier = @Resource,如果真需要byName形式加载,直接使用@Resource就可以了。

Spring Security和Swagger2集成报错的更多相关文章

  1. Spring Security 无法登陆,报错:There is no PasswordEncoder mapped for the id “null”

    编写好继承了WebSecurityConfigurerAdapter类的WebSecurityConfig类后,我们需要在configure(AuthenticationManagerBuilder ...

  2. 使用CXF+Spring发布WebService,启动报错

    使用CXF+Spring发布WebService,启动报错,日志如下: 五月 12, 2017 9:01:37 下午 org.apache.tomcat.util.digester.SetProper ...

  3. eclipes的Spring注解SequenceGenerator(name="sequenceGenerator")报错的解决方式

    eclipes的Spring注解SequenceGenerator(name="sequenceGenerator")报错的解决方式 右键项目打开Properties—>JA ...

  4. 【spring mvc】后台spring mvc接收List参数报错如下:org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.util.List]: Specified class is an interface

    后台spring mvc接收List参数报错如下:org.springframework.beans.BeanInstantiationException: Failed to instantiate ...

  5. spring boot启动STS 运行报错 java.lang.NoClassDefFoundError: ch/qos/logback/classic/LoggerContext

    spring boot启动STS 运行报错 java.lang.NoClassDefFoundError: ch/qos/logback/classic/LoggerContext 学习了: http ...

  6. Spring Boot 整合Spring Security 和Swagger2 遇到的问题小结

    How to configure Spring Security to allow Swagger URL to be accessed without authentication @Configu ...

  7. 笔记本电脑切换到无线热点无法联网问题&Spring Cloud相关工程启动报错问题

    通过禁用本地网络,和禁用另一个无线网络,以及禁用后重开,修改密码,重连的方式均失败后, 使用IE浏览器浏览提示失败,点击诊断,诊断出DNS服务器无响应异常. 突然想到通过ipconfig查看ip,网关 ...

  8. Spring Cloud和eureka启动报错 解决版本依赖关系

    导读 An attempt was made to call a method that does not exist. The attempt was made from the following ...

  9. 【Spring实战】—— 12 AspectJ报错:error at ::0 can't find referenced pointcut XXX

    今天在使用AspectJ进行注解切面时,遇到了一个错误. 切点表达式就是无法识别——详细报错信息如下: Exception can't find referenced pointcut perform ...

随机推荐

  1. iOS应用千万级架构:MVVM框架

    业务模块内的MVC和MVVM架构 目前,唯品会中MVC和MVVM架构并存,后期会偏重于MVVM架构的使用. MVC架构 Model:程序中要操纵的实际对象的抽象,为Controller提供经过抽象的业 ...

  2. Linux系统 Centos7 环境基于Docker部署Rocketmq服务

    消息队列 基本概述 MQ,Message Queue,基于TCP协议构建的简单协议,区别于具体的通信协议. 基于通信协议定义和抽象的更高层次的通信模型,一般都是生产者和消费者模型,又或者说服务端和客户 ...

  3. BUUCTF-Misc-No.4

    比赛信息 比赛地址:Buuctf靶场 内心os(蛮重要的) 我只想出手把手教程,希望大家能学会然后自己也成为ctf大佬,再来带带我QWQ 被偷走的文件 | SOLVED | foremost分离一下文 ...

  4. 基于SpringBoot AOP面向切面编程实现Redis分布式锁

    基于SpringBoot AOP面向切面编程实现Redis分布式锁 基于SpringBoot AOP面向切面编程实现Redis分布式锁 基于SpringBoot AOP面向切面编程实现Redis分布式 ...

  5. classpath路径(转)

    src不是classpath, WEB-INF/classes,lib才是classpathWEB-INF/ 是资源目录, 客户端不能直接访问, 这话是没错,不过现在的IDE编译器在编译时会把src下 ...

  6. mongodb(五):聚合操作(python)

    pymongo的聚合操作 数据类型样式 /* 1 */ { "_id" : ObjectId("5e5a32fe2a89d7c2fc05b9fc"), &quo ...

  7. Flask 基础组件(六):Session

    除请求对象之外,还有一个 session 对象.它允许你在不同请求间存储特定用户的信息.它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥. 设 ...

  8. python上selenium的弹框操作

    selenium之弹框操作 1,分类 弹框类型自见解分为四种: 1,页面弹框 2,警告提示框(alert) 3,确认消息框(confirm) 4,提示消息对话(prompt) 提示:selenium ...

  9. Spring Boot 2.3.0正式发布:优雅停机、配置文件位置通配符新特性一览

    当大潮退去,才知道谁在裸泳..关注公众号[BAT的乌托邦]开启专栏式学习,拒绝浅尝辄止.本文 https://www.yourbatman.cn 已收录,里面一并有Spring技术栈.MyBatis. ...

  10. 《Head First 设计模式》:装饰者模式

    正文 一.定义 装饰者模式动态地将责任(功能)附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 要点: 装饰者和被装饰者有相同的超类型. 可以用一个或多个装饰者包装一个对象. 既然装 ...