【发布时间】:2020-11-16 19:39:16
【问题描述】:
我一直在努力解决这个问题,但我就是不知道出了什么问题。
我有一个 Spring 应用程序,它使用 ApplicationContext.getBean() 来检索 2 个类似的类。我从 bean 查找中得到了错误的实例类。
这是 ApplicationContext 类:
public class DomainRegistryCab {
private static ApplicationContext applicationContext;
private static ApplicationContext createApplicationContext() {
return new AnnotationConfigApplicationContext( CaBridgeDomainServiceConfig.class );
}
public static CertificateProductApplicationService certificateProductAppService() {
var service = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
applicationContext().getAutowireCapableBeanFactory(),
CertificateProductApplicationService.class,
CaBridgeDomainServiceConfig.CERTIFICATE_PRODUCT_APP_SERVICE);
// var service = applicationContext().getBean(
// CaBridgeDomainServiceConfig.CERTIFICATE_PRODUCT_APP_SERVICE,
// CertificateProductApplicationService.class);
// var service = applicationContext().getBean(CertificateProductApplicationService.class);
validateDataSourceIs(DataSource.ProductDataStore, service.dataSource());
return service;
}
public static CertificateProgramApplicationService certificateProgramAppService() {
var service = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
applicationContext().getAutowireCapableBeanFactory(),
CertificateProgramApplicationService.class,
CaBridgeDomainServiceConfig.CERTIFICATE_PROGRAM_APP_SERVICE);
// var service = applicationContext().getBean(
// CaBridgeDomainServiceConfig.CERTIFICATE_PROGRAM_APP_SERVICE,
// CertificateProgramApplicationService.class);
// service = applicationContext().getBean(CertificateProgramApplicationService.class);
validateDataSourceIs(DataSource.ProgramDataStore, service.dataSource());
return service;
}
这里是 CaBridgeDomainServiceConfig:
@Configuration
@ComponentScan(basePackageClasses = { HibernateConfigurationMarker.class })
public class CaBridgeDomainServiceConfig {
public static final String CERTIFICATE_PRODUCT_APP_SERVICE = "certificateProductAppService";
public static final String CERTIFICATE_PROGRAM_APP_SERVICE = "certificateProgramAppService";
@Bean(name= CERTIFICATE_PRODUCT_APP_SERVICE)
public CertificateProductApplicationService certificateProductAppService() {
return new CertificateProductApplicationServiceCabImpl();
}
@Bean(name= CERTIFICATE_PROGRAM_APP_SERVICE)
public CertificateProgramApplicationService certificateProgramAppService() {
return new CertificateProgramApplicationServiceCabImpl();
}
}
public interface CertificateProductApplicationService extends CertificateApplicationService {
}
public interface CertificateProductApplicationService extends CertificateApplicationService {
}
public interface CertificateApplicationService {
}
如果我调用 DomainRegistryCab.certificateProductAppService() 使用上述类,我会得到一个 CertificateProgramApplicationService 实例而不是 CertificateProductApplicationService。
如果我使用这种方法,我会得到类似的结果:
public static CertificateProductApplicationService certificateProductAppService() {
var service = applicationContext().getBean(
CaBridgeDomainServiceConfig.CERTIFICATE_PRODUCT_APP_SERVICE,
CertificateProductApplicationService.class);
validateDataSourceIs(DataSource.ProductDataStore, service.dataSource());
return service;
}
我也尝试过让@Bean 方法返回实现类和 ApplicationContext().getBean() 来请求实现类而不是接口:
public class DomainRegistryCab {
private static ApplicationContext applicationContext;
private static ApplicationContext createApplicationContext() {
return new AnnotationConfigApplicationContext( CaBridgeDomainServiceConfig.class );
}
public static CertificateProductApplicationService certificateProductAppService() {
var service = applicationContext().getBean(CertificateProductApplicationServiceCabImpl.class);
validateDataSourceIs(DataSource.ProductDataStore, service.dataSource());
return service;
}
public static CertificateProgramApplicationService certificateProgramAppService() {
var service = applicationContext().getBean(CertificateProgramApplicationServiceCabImpl.class);
validateDataSourceIs(DataSource.ProgramDataStore, service.dataSource());
return service;
}
public static ApplicationContext applicationContext() {
if (applicationContext == null)
applicationContext = createApplicationContext();
return applicationContext;
}
}
@ComponentScan(basePackageClasses = { HibernateConfigurationMarker.class })
public class CaBridgeDomainServiceConfig {
@Bean(name= CERTIFICATE_PRODUCT_APP_SERVICE)
public CertificateProductApplicationServiceCabImpl certificateProductAppService() {
return new CertificateProductApplicationServiceCabImpl();
}
@Bean(name= CERTIFICATE_PROGRAM_APP_SERVICE)
public CertificateProgramApplicationServiceCabImpl certificateProgramAppService() {
return new CertificateProgramApplicationServiceCabImpl();
}
}
这段代码导致spring根本找不到实现类:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cmb.cabridge.application.cert.CertificateProductApplicationServiceCabImpl' available
【问题讨论】:
-
我认为您的第一种方法没有任何问题。您可以在创建应用程序上下文后通过打印所有
spring-beans来尝试调试以验证上下文中存在哪些bean?见baeldung.com/spring-show-all-beans -
是的,我已启用 Spring 框架日志记录到 DEBUG,它显示它找到了两个 bean。我还打印了 ApplicationContext.getBeanDefinitionNames() 它还显示了两个 bean。
-
你能在 github.com 上重现它吗?你用的是什么春季版本?
-
抱歉,我们不能将它作为专有应用程序发布到 github 上。使用springframework 5.16.RELEASE.
-
刚刚更新到 springframework 5.2.11.RELEASE 和 spring boot 2.3.6.RELEASE 仍然有同样的问题。