所以我为 CDI 创建了一些类。它看起来不错,而且效果很好。
具有类型的限定符类:
@Qualifier
@Retention(RUNTIME)
@Target( {TYPE, METHOD, FIELD, PARAMETER} )
public @interface DaoQualifier
{
public enum DatasourceType { FILE, JPA, MEMORY }
public DatasourceType type();
}
工厂类,它返回正确的接口实例:
@ApplicationScoped
public class ConfigurationReaderDaoFactory implements Serializable
{
private static final long serialVersionUID = -7097322271912690164L;
private static final Logger LOGGER = Logger.getLogger( ConfigurationReaderDaoFactory.class.getName() );
private final String LOG_MESSAGE = "getting ConfigurationReaderDao ejb remote reference for %s datasource";
@Produces
@DaoQualifier(type = DatasourceType.MEMORY)
public ConfigurationReaderDao getMemoryDao() throws NamingException
{
LOGGER.finer( String.format(LOG_MESSAGE, DatasourceType.MEMORY) );
String jndi = ""java:global/earName/ejbName/MemoryConfigurationReaderDao!a.b.c.ConfigurationReaderDao";";
return (ConfigurationReaderDao) InitialContextGenerator.getInitialContext().lookup(jndi);
}
@Produces
@DaoQualifier(type = DatasourceType.JPA)
public ConfigurationReaderDao getJpaDao() throws NamingException
{
LOGGER.finer( String.format(LOG_MESSAGE, DatasourceType.JPA) );
String jndi = ""java:global/earName/ejbName/JpaConfigurationReaderDao!a.b.c.ConfigurationReaderDao";";
return (ConfigurationReaderDao) InitialContextGenerator.getInitialContext().lookup(jndi);
}
...
}
通过@Inject 注解易于使用:
public class ConfigurationReaderService
{
@Inject
@DaoQualifier(type = DatasourceType.MEMORY)
private ConfigurationReaderDao configurationReaderDaoService;
public String getStringSystemParam(final String key)
{
String value = null;
if (key != null)
{
value = configurationReaderDaoService.getStringSystemParam(key);
}
}
}
我喜欢这个解决方案,因为它很容易阅读和理解。
我只剩下三个问题了:
(1) 我需要弄清楚的最后一件小事是:在我当前的实现中,类型参数是硬编码的:
@Inject
@DaoQualifier(type = DatasourceType.MEMORY)
private ConfigurationReaderDao configurationReaderDaoService;
type 参数来自管理员管理的应用程序配置。所以我需要以某种方式动态注入接口的正确实现,它依赖于字符串变量的简单值。
我想我需要以某种方式使用@Any 注释。
(2) 我尝试在ConfigurationReaderDaoFactory 类的开头使用@RequestScoped 注释,但它不起作用。我得到了一个 WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped 异常。
(3) 为什么在我的情况下使用 CDI 注入比直接使用我的 ConfigurationReaderDaoFactory 类更好?如果我直接使用我的工厂类,我不需要DaoQualifier 类,也不需要弄清楚动态注入过程。更少的类和代码总是更好:-)