【问题标题】:What's wrong within the usage of BeanFactoryAnnotationUtils?BeanFactoryAnnotationUtils 的使用有什么问题?
【发布时间】:2015-12-24 11:04:29
【问题描述】:

我正在尝试对方法进行简单的调用

BeanFactoryAnnotationUtils.qualifiedBeanOfType

这里是项目的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>beanfactoryannotationutils.sample</groupId>
<artifactId>BeanFactoryAnnotationUtilsProblem</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.1.RELEASE</version>
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
</properties>

<dependencies>
    <!-- Spring boot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot</artifactId>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Application.java

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);

        ListableBeanFactory beanFactory = ctx.getBeanFactory();

        // This is working ... (@Autowired with @Qualifier(...) too)
        Map<String, QualifiedInterface> qualifiedBeans = beanFactory.getBeansOfType(QualifiedInterface.class);
        System.out.println("Existing qualified beans ...");
        for (QualifiedInterface qualifiedBean : qualifiedBeans.values()) {
            System.out.println(" " + qualifiedBean.toString());
            for (Annotation annotation : qualifiedBean.getClass().getAnnotations()) {
                System.out.println(" - " + annotation.toString());
            }
        }

        // This is working too ...
        Map<String, Object> qualifiedBeansFromCtx = ctx.getBeansWithAnnotation(Qualifier.class);
        System.out.println("Existing qualified beans from context ...");
        for (Object qualifiedBean : qualifiedBeansFromCtx.values()) {
            System.out.println(" " + qualifiedBean.toString());
            for (Annotation annotation : qualifiedBean.getClass().getAnnotations()) {
                System.out.println(" - " + annotation.toString());
            }
        }

        // This is not ...
        QualifiedInterface processor = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
            beanFactory, QualifiedInterface.class, "QualifierA");

        System.out.println("The selected processor should be A " + processor);
    }
}

一个接口QualifiedInterface.java

public interface QualifiedInterface {

}

两个bean QualifiedA.java

@Component
@Qualifier("QualifierA")
public class QualifiedA implements QualifiedInterface {

    @Override
    public String toString() {
        return "QualifiedA";
    }
}

QualifiedB.java

@Component
@Qualifier("QualifierB")
public class QualifiedB implements QualifiedInterface {

    @Override
    public String toString() {
        return "QualifiedB";
    }
}

整个在同一个包和应用程序中,现在运行它:

2015-12-24 15:08:34.468  INFO 9524 --- [           main] l.p.e.b.Application                      : Starting Application on DTBE-DEV4 with PID 9524 (D:\Workspace_netbeans\BeanFactoryAnnotationUtilsProblem\target\classes started by eguenichon in D:\Workspace_netbeans\BeanFactoryAnnotationUtilsProblem)
2015-12-24 15:08:34.478  INFO 9524 --- [           main] l.p.e.b.Application                      : No profiles are active
2015-12-24 15:08:34.618  INFO 9524 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@11e18e8c: startup date [Thu Dec 24 15:08:34 CET 2015]; root of context hierarchy
2015-12-24 15:08:37.516  INFO 9524 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2015-12-24 15:08:37.524  INFO 9524 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2015-12-24 15:08:37.672  INFO 9524 --- [           main] l.p.e.b.Application                      : Started Application in 3.715 seconds (JVM running for 4.355)
Existing qualified beans ...
 QualifiedA
 - @org.springframework.stereotype.Component(value=)
 - @org.springframework.beans.factory.annotation.Qualifier(value=QualifierA)
 QualifiedB
 - @org.springframework.stereotype.Component(value=)
 - @org.springframework.beans.factory.annotation.Qualifier(value=QualifierB)
Existing qualified beans from context ...
 QualifiedA
 - @org.springframework.stereotype.Component(value=)
 - @org.springframework.beans.factory.annotation.Qualifier(value=QualifierA)
 QualifiedB
 - @org.springframework.stereotype.Component(value=)
 - @org.springframework.beans.factory.annotation.Qualifier(value=QualifierB)
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'QualifierA' is defined: No matching QualifiedInterface bean found for qualifier 'QualifierA' - neither qualifier match nor bean name match!
    at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeanOfType(BeanFactoryAnnotationUtils.java:100)
    at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeanOfType(BeanFactoryAnnotationUtils.java:56)
    at beanfactoryannotation.sample.beanfactoryannotationutilsproblem.Application.main(Application.java:45)
2015-12-24 15:08:37.684  INFO 9524 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@11e18e8c: startup date [Thu Dec 24 15:08:34 CET 2015]; root of context hierarchy
2015-12-24 15:08:37.686  INFO 9524 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 0
2015-12-24 15:08:37.691  INFO 9524 --- [       Thread-1] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

BeanFactoryAnnotationUtils.qualifiedBeanOfType 似乎不起作用,因为合格的 bean 存在于上下文中但无法检索。你知道这里有什么问题吗?

谢谢!

【问题讨论】:

  • 可能是错字? "QualifierA""QualifiedA"
  • 你是对的,但是在重写案例时这是一个错误,最初我有一个枚举。我将问题固定为 QualifiedA。谢谢!

标签: java spring spring-annotations


【解决方案1】:

由于 BeanFactoryAnnotationUtils 类的默认规范,在 Spring 4.3 之前不提供此功能。

见:https://jira.spring.io/browse/SPR-13819

【讨论】:

    【解决方案2】:

    查看 BeanFactoryAnnotationUtils.qualifiedBeanOfType(...) 方法背后的代码时,我注意到从 AbstractBeanDefinition 对象检查限定符。当我将这个对象转储到我们的示例中时,我可以注意到“限定符”映射是空的?!?!?

    它看起来像一个 Spring 使用带注释的限定符加载 bean 定义的方式中的错误

    已经有一个看起来非常相似的未解决问题:https://jira.spring.io/browse/SPR-13452

    我想你可以专门用你的测试用例打开另一个。

    【讨论】:

      猜你喜欢
      • 2011-03-08
      • 2011-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-13
      • 2011-04-24
      • 2010-10-21
      • 1970-01-01
      相关资源
      最近更新 更多