1

注入する Bean サブクラスを指定する修飾子を定義しました。注入ポイントで修飾子にパラメーターが指定されていない場合、すべてが期待どおりに機能します。インジェクション ポイントで属性と値を指定すると、CDI unsatisfied dependency エラーが発生します。私は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

4

1 に答える 1

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) {
            }
        }`
于 2013-09-18T15:45:51.703 に答える