我的类中有两个字段:
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告诉我:
具有限定符的ClassA类型的依赖项不满足@默认
然而,CDI告诉我关于ClassB b
字段的任何信息。
然后,我添加了一个@Dependent
注释:
@Inject @Dependent private ClassA a;
CDI告诉我一样。
但是,如果我用@New
CDI注释该字段,则可以工作。
为什么我使用@New
作品?为什么CDI没有告诉我关于另一个属性Class B
的一些信息?
这个限定符注释(@Dependent
)位于类定义本身或bean的生产者上。不在注射点上。
另外,不要使用@New
。它已被弃用。它的功能与dependent相同,但从注入点一侧驱动,而CDI则集中在生产者一侧。
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将始终知道在哪个注入点注入哪个实现或哪个类型,这不会抱怨类型的模糊性。