太好了,我获得了两次 -2 票(-4 声望),因为我问了软件开发人员的高级主题?
我搜索了关于stackoverflow并找到了这个
Stack Overflow 成立于 2008 年,是最大、最值得信赖的在线社区,供开发人员学习、分享知识和建立职业生涯......
如果对这个话题感兴趣,那么:
经过几个小时了解 CDI Bean 和 EJB 作为独立模块(JBoss 模块)使用时生命周期之间的差异后,我发现:
单例 CDI Bean 每个模块实例化一次,而不是所有模块中的真正单例。
为了避免这种情况,我必须将注册表创建为单例企业会话 Bean。这带来了新问题,CDI 注入在模块之间不起作用,所以我必须打包一个 CDI 生产者(我不在乎它是否是单例的,它只是一个生产者),它可以被任何模块实例化。这个生产者的主要职责是查找注册表 EJB,以避免每次我需要访问注册表时硬编码 jndi 路径。
我更改了我的简单示例以支持 JSF 插件,这是我当前使用的示例。
模块面:
注册表界面:
public interface FaceletsModuleRegistry {
void registerModule(String module);
List<String> getRegisteredModules();
}
注册表实现:
@Local(FaceletsModuleRegistry.class)
@Singleton(name="FaceletsModuleRegistry")
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
@Vetoed
public class FaceletsModuleRegistryImpl implements FaceletsModuleRegistry {
private Set<String> registeredModuleNames = new TreeSet<>();
@Override
public void registerModule(String module) {
registeredModuleNames.add(module);
}
@Override
public List<String> getRegisteredModules() {
return Collections.unmodifiableList(new ArrayList<>(registeredModuleNames));
}
}
注册表制作人:
@ApplicationScoped
public class FaceletsModuleRegistryBuilder {
@EJB(lookup="java:global/facelets/FaceletsModuleRegistry!co.hatit.enterprise.facelets.services.FaceletsModuleRegistry")
protected FaceletsModuleRegistry faceletsModuleRegistry;
@Produces
public FaceletsModuleRegistry getFaceletsModuleRegistry(){
return faceletsModuleRegistry;
}
}
我想要插入的任何其他模块都实现了此代码(请参阅@Inject
可用于任何需要访问注册表单例实例的模块):
@ApplicationScoped
public class InmueblesActivator {
@Inject
private FaceletsModuleRegistry faceletsModuleRegistry;
public void init(@Observes @Initialized(ApplicationScoped.class) Object init){
String moduleName = Module.getCallerModule().getIdentifier().getName();
String name = StringUtils.substringBetween(moduleName, "deployment.", ".jar");
faceletsModuleRegistry.registerModule(name);
}
}
然后我可以从任何模块引用 Registry 作为一个真正的单例实例(解决了我在多个模块中使用 CDI 单例 bean 时具有相同类的多个实例的问题)。
现在,我可以插入 JEE 模块,不仅是 java 代码,还包括 facelets 资源:
public class FaceletsResourceHandler extends ResourceHandlerWrapper {
Logger logger = LoggerFactory.getLogger(FaceletsResourceHandler.class);
@Inject
FaceletsModuleRegistry faceletsModuleRegistry;
private ResourceHandler wrapped;
public FaceletsResourceHandler(ResourceHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public ViewResource createViewResource(FacesContext context, final String name) {
ViewResource resource = super.createViewResource(context, name);
if (resource == null) {
resource = new ViewResource() {
@Override
public URL getURL() {
try {
//iterates over plugins to find the required resource.
for(String module : faceletsModuleRegistry.getRegisteredModules()){
URL resource = Module.getCallerModule().getModuleLoader()
.loadModule(ModuleIdentifier.create("deployment." + module + ".jar"))
.getExportedResource("META-INF/resources" + name);
if (resource != null) return resource;
}
} catch (ModuleLoadException e) {
throw new FacesException(e);
}
return null;
}
};
}
return resource;
}
@Override
public ResourceHandler getWrapped() {
return wrapped;
}
}