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
- UserDao 是一个 UserDao
- UserDaoMongoImpl 是一个 UserDao
- 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 将始终知道在哪个注入点注入哪个实现或哪个类型,这不会抱怨类型歧义。
我的 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
- UserDao 是一个 UserDao
- UserDaoMongoImpl 是一个 UserDao
- 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 将始终知道在哪个注入点注入哪个实现或哪个类型,这不会抱怨类型歧义。