这个问题将从我一年前写的my blog post中引用.
虽然我为我的DAO使用自定义CDI限定符,但我想知道是否有动态注入DAO的方法.
我问的原因如下.目前我有3个CDI限定符,@ HibernateDAO(用于Hibernate会话注入类型DAO),@ JPADAO(用于JPA特定DAO)和@JDBCDAO(用于纯JDBCDAO).这要求我必须在每个具体实现上指定它,并在注入时如此.
@Inject @JPADAO
private CustomerDAO customerDAO;
有没有更好的方法可以让我添加各种风格的DAO而无需更改代码,编译和部署?
我想在我的项目的下一个版本中介绍MongoDB,我想我是否可以放弃@MongoDBDAO和注入,如,
@Inject @MongoDBDAO
private CustomerDAO customerDAO;
我知道CDI Injection可以允许默认和替代注射.我希望其他开发人员可以使用覆盖默认实现与另一个子类,并能够在不更改现有服务代码的情况下注入它.
这种效果的东西:
@Inject @DAO
private CustomerDAO customerDAO;
其中@DAO可以是任何风格的任何DAO(甚至来自第三方),并以某种方式将@DAO映射到第一个找到备选,如果没有找到,则使用默认实现.
谢谢.
哦!此解决方案必须严格使用最新(作为当前编写时)Java EE CDI规范.使用的技术:
> RedHat JBoss Wildfly 8.2.0 Final(完全符合Java EE 7).
> Java 8.
> Java EE 7 API.
我不会下载使用Spring Framework的解决方案,因为它可以帮助其他Spring开发人员.
解决方法:
如果你想在运行时一般注入Daos,我会推荐这种方法.
@Qualifier
@Retention(RUNTIME)
@Target({TYPE,METHOD,FIELD,PARAMETER})
public @interface DAO{
String value();
}
//Dont worry, CDI allows this quite often than not ;)
public class DAOImpl extends AnnotationLiteral implements DAO {
private final String name;
public DAOImpl(final String name) {
this.name = name;
}
@Override
public String value() {
return name;
}
}
在需要的地方.
@ApplicationScoped; //Or Whatever
public class MyDAOConsumer {
@Inject
@Any
private Instance daoServices;
//Just as an example where you can get the dynamic configurations for selecting daos.
//Even from property files, or system property.
@Inject
private MyDynamicConfigurationService myDanamicConfigurationService;
public void doSomethingAtRuntime() {
final String daoToUse = myDanamicConfigurationService.getCurrentConfiguredDaoName();
final DAO dao = new DAOImpl(daoToUse);
//Careful here if the DaoService does not exist, you will get UnsatisfiedException
final DAOService daoService = daoServices.select(dao).get();
daoService.service();
}
}
并且碰撞,你可以配置在运行时使用哪个dao毫不费力.
并且不会改变任何微小的代码.
标签:java,dependency-injection,java-ee,cdi
来源: https://codeday.me/bug/20190612/1222944.html