欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

深入 Spring Boot:奈何排查 CAD加密 expected single matching bean but

点击: 次  来源:昆山软开发 时间:2018-01-18

原文出处: hengyunabc

写在前面

这个demo来说明怎么排查一个常见的spring expected single matching bean but found 2的异常。

https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-expected-single

调试排查 expected single matching bean but found 2 的错误

把工程导入IDE里,直接启动应用,抛出来的异常信息是:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected single matching bean but found 2: pDataSource1,pDataSource2
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1041) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1090) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.init(DataSourceInitializer.java:71) ~[spring-boot-autoconfigure-1.4.7.RELEASE.jar:1.4.7.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_112]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    ... 30 common frames omitted

许多人遇到这种错误时,就乱设置一通,找不到下手的步伐。其实耐性排查下,是很简朴的。

抛出异常的原因

异常信息写得很清楚了,昆山软件开发,在spring context里需要注入/获取到一个DataSource bean,可是此刻spring context里呈现了两个,它们的名字是:pDataSource1,pDataSource2

那么有两个问题:

  1. 应用是在那边要注入/获取到一个DataSource bean?
  2. pDataSource1,pDataSource2 是在那边界说的?

利用 Java Exception Breakpoint

在IDE里,新建一个断点,范例是Java Exception Breakpoint(假如不清楚怎么添加,可以搜索对应IDE的利用文档),异常类是上面抛出来的NoUniqueBeanDefinitionException。

当断点愣住时,查察栈,可以很清楚地找到是在DataSourceInitializer.init() line: 71这里要获取DataSource:

Thread [main] (Suspended (exception NoUniqueBeanDefinitionException))
    owns: ConcurrentHashMap<K,V>  (id=49)
    owns: Object  (id=50)
    DefaultListableBeanFactory.resolveNamedBean(Class<T>, Object...) line: 1041
    DefaultListableBeanFactory.getBean(Class<T>, Object...) line: 345
    DefaultListableBeanFactory.getBean(Class<T>) line: 340
    AnnotationConfigEmbeddedWebApplicationContext(AbstractApplicationContext).getBean(Class<T>) line: 1090
    DataSourceInitializer.init() line: 71
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 62
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43
    Method.invoke(Object, Object...) line: 498
    InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(Object) line: 366
    InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(Object, String) line: 311
    CommonAnnotationBeanPostProcessor(InitDestroyAnnotationBeanPostProcessor).postProcessBeforeInitialization(Object, String) line: 134
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).applyBeanPostProcessorsBeforeInitialization(Object, String) line: 409
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1620
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 555
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 483
    AbstractBeanFactory$1.getObject() line: 306
    DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 230
    DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 302
    DefaultListableBeanFactory(AbstractBeanFactory).getBean(String, Class<T>, Object...) line: 220
    DefaultListableBeanFactory.resolveNamedBean(Class<T>, Object...) line: 1018
    DefaultListableBeanFactory.getBean(Class<T>, Object...) line: 345
    DefaultListableBeanFactory.getBean(Class<T>) line: 340
    DataSourceInitializerPostProcessor.postProcessAfterInitialization(Object, String) line: 62
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).applyBeanPostProcessorsAfterInitialization(Object, String) line: 423
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1633
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 555
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 483
    AbstractBeanFactory$1.getObject() line: 306
    DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 230
    DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 302
    DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 197
    DefaultListableBeanFactory.preInstantiateSingletons() line: 761
    AnnotationConfigEmbeddedWebApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 867
    AnnotationConfigEmbeddedWebApplicationContext(AbstractApplicationContext).refresh() line: 543
    AnnotationConfigEmbeddedWebApplicationContext(EmbeddedWebApplicationContext).refresh() line: 122
    SpringApplication.refresh(ApplicationContext) line: 762
    SpringApplication.refreshContext(ConfigurableApplicationContext) line: 372
    SpringApplication.run(String...) line: 316
    SpringApplication.run(Object[], String[]) line: 1187
    SpringApplication.run(Object, String...) line: 1176
    DemoExpectedSingleApplication.main(String[]) line: 17

定位那边要注入/利用DataSource