CDI @Dependent 和@New

CDI @Dependent and @New

我的 class 中有两个字段:

public class Class {

    @Inject private ClassA a;
    @Inject private ClassB b;

    public void search(String lqlSentence)
    {
        this.a.something();
        AnotherClass anotherOne = new AnotherOne;
        anotherOne.method(this.b);
    }
}

CDI 告诉我:

Unsatisfied dependencies for type ClassA with qualifiers @Default

但是,CDI 告诉我有关 ClassB b 字段的任何信息。

然后,我添加了一个 @Dependent 注释:

@Inject @Dependent private ClassA a;

CDI 告诉我同样的事情。

但是,如果我用 @New CDI 注释该字段。

为什么我使用 @New 有效? 为什么 CDI 不告诉我关于另一个 属性 Class B?

此限定符注释 (@Dependent) 继续 class 定义本身,或 bean 的生产者。不在注入点上。

另外,不要使用 @New。它已弃用。它的功能与依赖相同,但从注入点侧驱动,而 CDI 侧重于生产者侧。

Java EE 中的 CDI 与 "Types" 配合使用。 因此,如果您有一个由不同 类 实现的接口,并且您正在尝试注入该接口,那么 CDI 将抱怨类型歧义,因为它无法解析要注入的 bean 实例的类型。 例如: 假设我们有这样的东西:

public interface UserDao{
   // methods......
}

public class UserDaoMongoImpl implements UserDao{
  //Mongo db implementations....
}

public class UserDaoOrclImpl implements UserDao{
  // oracle Db specific implementations for userDao
}

@Stateless
public class UserServiceImpl implements UserService{

  @Inject private UserDao userDao; //injectPoint

  //service impl ...

}

那么这里 CDI 将无法确定要注入哪个实现,因为现在我们有三种不同类型的 UserDao

  1. UserDao 是一个 UserDao
  2. UserDaoMongoImpl 是一个 UserDao
  3. UserDaoOrclImpl 是一个 UserDao

这给 CDI 带来了各种混乱。

现在为了克服这个问题,我们有简单的注释限定符。

所以上面的代码变成了这样的:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.TYPE})
public @interface MongoImplementation {
} 

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.TYPE})
public @interface OrclImplementation {
} 


public interface UserDao{
   // methods......
}

@MongoImplementation
public class UserDaoMongoImpl implements UserDao{
  //Mongo db implementations....
}

@OrclImplementation
public class UserDaoOrclImpl implements UserDao{
  // oracle Db specific implementations for userDao
}

@Stateless
public class UserServiceImpl implements UserService{

  @Inject @MongoImplementation     //Injection point A
  private UserDao mongoUserDao;

  @Inject @OrclImplementation      //Injection point B
  private UserDao orclUserDao;

  //service impl ...

}

所以现在使用这个 CDI 将始终知道在哪个注入点注入哪个实现或哪个类型,这不会抱怨类型歧义。