使用注释参数时为什么CDI不满足依赖性?

时间:2013-09-18 14:06:17

标签: java annotations glassfish cdi

我已经定义了一个限定符来指定我想要注入的bean子类。当限定符没有在注入点指定参数时,一切都按预期工作。当我在注入点指定属性和值时,我得到CDI不满足的依赖性错误。我正在使用Glassfish 4.0进行部署。此外,在注入的bean上使用无界面视图,但我认为在这种情况下不重要。

限定符的目的是获取Postgres特定的子类(正在使用各种不同的数据库,以比较任何行为差异)。该参数用于指定Postgres模式(默认为“public”)。

限定符在Postgres.java

中定义如下
@Qualifier
@Retention(RUNTIME)
@Target({ FIELD, TYPE, METHOD })
public @interface Postgres
{
  String schema() default "public";
}

注入的子类在DBCmdPostgres.java

中看起来像这样
@Stateless
@Postgres
public class DBCmdPostgres
    extends DBCmd
{
...
  @PostConstruct
  public void postConstruct()
  {
    Class cl = getClass();
    Postgres postgresAnnotation = (Postgres)cl.getAnnotation(Postgres.class);
    if (postgresAnnotation != null) {
      System.out.println(">> @Postgres(schema = " + postgresAnnotation.schema() +")");
    }
  }
...
}

DBCmd.java中的基类如下所示:

@Stateless
@Default
abstract public class DBCmd
{
...
}

注入点是JSF会话范围的支持bean indexBacker.java

  @Inject @Postgres(schema = "foo") private DBCmd postgresCmds;

如果我在注入点省略(schema = "foo"),那么事情就像我期望的那样,并且PostConstruct方法显示正确的“public”默认值。如果我添加(schema = "foo")部分,我在部署到Glassfish时会收到以下错误:

[2013-09-18T08:36:24.209-0500] [glassfish 4.0] [SEVERE] [] [javax.enterprise.system.core] [tid: _ThreadID=36 _ThreadName=admin-listener(3)] [timeMillis: 1379511384209] [levelValue: 1000] [[
  Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [DBCmd] with qualifiers [@Postgres] at injection point [[BackedAnnotatedField] @Inject @Postgres private jsfBackers.IndexBacker.postgresCmds]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [DBCmd] with qualifiers [@Postgres] at injection point [[BackedAnnotatedField] @Inject @Postgres private jsfBackers.IndexBacker.postgresCmds]
    at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:403)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:325)
    at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:177)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:208)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:519)
    at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:505)
    at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:480)
    at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:536)
    at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:216)
    at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
    at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:328)
...

这些bean目前是@Stateless,但如果我们可以弄明白是什么,它们将成为@Stateful(存储/使用schema参数的值,以及其他一些东西)错误。

1 个答案:

答案 0 :(得分:1)

您的参数应标记为@Nonbinding,以便正确解析。

要读取值:

其中ip是你的InjectionPoint对象,annotationClass是你想要读的类(T是它的类型)

final Set<Annotation> annotations = ip.getQualifiers();
        for (final Annotation a : annotations) {
            try {
                if (a.annotationType().isAssignableFrom(annotationClass)) {
                    t = (T) a;
                    break;
                }
            }
            catch (final ClassCastException e) {
            }
        }`