简体   繁体   English

Spring ApplicationContext.getBean 返回错误的类

[英]Spring ApplicationContext.getBean returns wrong class

I've been beating my head over this and I just can't figure out what's wrong.我一直在为此痛心疾首,但我无法弄清楚出了什么问题。

I have a Spring app which uses ApplicationContext.getBean() to retrieve 2 similar classes.我有一个 Spring 应用程序,它使用 ApplicationContext.getBean() 来检索 2 个类似的类。 I'm getting the wrong instance class from the bean lookup.我从 bean 查找中得到了错误的实例类。

Here's ApplicationContext class:这是 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;
    }

Here is CaBridgeDomainServiceConfig:这是 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 {
}

Using the above classes if I call DomainRegistryCab.certificateProductAppService() I get an instance of CertificateProgramApplicationService not CertificateProductApplicationService.如果我调用 DomainRegistryCab.certificateProductAppService() 使用上述类,我会得到一个 CertificateProgramApplicationService 的实例,而不是 CertificateProductApplicationService。

I get similar results if I use this method:如果我使用这种方法,我会得到类似的结果:

public static CertificateProductApplicationService certificateProductAppService() {
    var service = applicationContext().getBean(
        CaBridgeDomainServiceConfig.CERTIFICATE_PRODUCT_APP_SERVICE,
        CertificateProductApplicationService.class);
    validateDataSourceIs(DataSource.ProductDataStore, service.dataSource());
    return service;
}

I've also tried having the @Bean methods return the implementation classes and the ApplicationContext().getBean() to request the implementation classes instead of the interfaces:我还尝试让 @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();
    }
}

This code results in spring not finding the implementation classes at all:此代码导致 spring 根本找不到实现类:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cmb.cabridge.application.cert.CertificateProductApplicationServiceCabImpl' available

I was eventually able to get things to work using the applicationContext().getBean("beanName", CertificateProductApplicationService.class).我最终能够使用 applicationContext().getBean("beanName", CertificateProductApplicationService.class) 开始工作。 The problem was deeper in my code in the CertificateProductApplicationServiceCabImpl class which used and returned the wrong datasource.问题在我的 CertificateProductApplicationServiceCabImpl 类中的代码中更深层次,该类使用并返回了错误的数据源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM