如何以静态方法以编程方式将Java CDI 1.1+托管bean注入局部变量?
我用CDI做了一个小测试项目.我的应用程序由EJB EAR和WAR组成,全部部署在Glassfish 4上.我正在使用Hibernate 4.3.4来访问数据库.
我的目标是验证EJB(DAO)中的类是否可以接收EntityManager的注入.
SessionBean + EJB模式并不是很棒,但我必须修改已经创建的应用程序,所以我没有太多选择.
这是我的EJB代码:
@Named
public class DAOTest implements Serializable {
private static final long serialVersionUID = 1L;
@PersistenceContext(unitName="CDI-ejb")
private EntityManager em;
public void test(){
//em.getClass();
}
public EntityManager getEm() {
return em;
}
public void setEm(EntityManager em) {
this.em = em;
}
public DAOTest() {
// TODO Auto-generated constructor stub
}
}
Run Code Online (Sandbox Code Playgroud)
Service.java
@Stateless
@LocalBean
public class Service implements ServiceLocal {
@Inject DAOTest test;
/**
* Default constructor.
*/
public Service() {
// TODO …Run Code Online (Sandbox Code Playgroud) 我在浏览jsf项目中的页面时遇到BusyConversationException.如果用户在ajax调用期间尝试导航到另一个页面,则通常会发生这种情况.当用户在单击另一个链接后立即单击链接而不等待加载页面时,也会发生这种情况.
例如,如果用户点击通过类似于下面的代码生成的多个链接,我们肯定会得到此异常.另一个例子是,假设用户在文本字段上输入查询,我们的应用程序进行ajax调用以搜索此查询.在该查询期间,如果用户单击某个按钮以导航到另一个页面,则也会发生BusyConversationException.
<h:commandLink value="#{theProfile.profileName}"
title="#{theProfile.profileName}"
action="#{profileBean.aProfileSelected}">
<f:setPropertyActionListener target="#{currentProfileWebBean.theProfile}" value="#{theProfile}"/>
</h:commandLink>
Run Code Online (Sandbox Code Playgroud)
我能赶上在一个延伸ExceptionHandlerWrapper类中的ExceptionHandler类这种类型的异常,但我不能挽救我目前的状态,我可以为这种情况下做的最好的是,当这个例外发生时重定向到主页.
有没有解决方案来避免这种情况?提前感谢您的回答和评论.
我正在使用NetBeans和Glassfish 4.1.1开发一个webapp.我正在使用JSF和CDI来管理facelets的后台bean.在更改代码中的任何内容后不久,在通过浏览器"成功"部署和运行应用程序后,我总是会遇到此IllegalStateException的内部服务器错误:
org.jboss.weld.exceptions.IllegalStateException: WELD-000227: Bean
identifier index inconsistency detected - the distributed container
probably does not work with identical applications
Run Code Online (Sandbox Code Playgroud)
我可以通过干净,构建和重新部署来摆脱它.但无论如何,NetBeans在每次保存后都会自动重新部署.所以我仍然需要点击清洁和构建,然后重新部署自己总是在任何小改变后,它让我疯了!
那么我可以在glassfish服务器上更改任何设置以避免这种情况,或者我可以告诉NetBeans在自动部署之前清理和构建吗?
它并不总是这样,最近我更新了玻璃鱼,它可能只是在那之后出现,我不记得了.
提前致谢!这花了我很多时间..
解决了
我再次谷歌搜索了几个小时,找到了解决方案:我在glassfish中设置了一个新的系统属性
org.jboss.weld.serialization.beanIdentifierIndexOptimization = false
为了避免出现不一致,如WELD参考文献中所述:
我使用的代码如下:
public Configuration {
private boolean isBatmanCar = someMethod(...);
@Produces
public Car getCar(@New Car car) {
if(isBatmanCar) {
car.setName("BatmanCar");
}
return car;
}
}
public Car {
private String name = "NormalCar";
public void setName(String name) {
this.name = name;
}
}
public Demo {
@Inject
Car car;
// rest of code
}
Run Code Online (Sandbox Code Playgroud)
当我将应用程序部署到glassfish(Java EE 6顺便说一句)时,我得到了
AmbiguousResolutionException: WELD-001318 Cannot resolve an ambiguous dependency between (...) Car with qualifiers [@Any @Default] (...) Producer Method [Car] with qualifiers [@Any @Default]
我知道当我添加@Alternative …
尝试将参数注入CDI bean(ApplicationScoped)的构造函数时,遇到以下问题:
Caused by: org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001435: Normal scoped bean class xx.Config is not proxyable because it has no no-args constructor - Managed Bean [class xx.Config] with qualifiers [@Default @Named @Any].
at org.jboss.weld.bean.proxy.DefaultProxyInstantiator.validateNoargConstructor(DefaultProxyInstantiator.java:50)
at org.jboss.weld.util.Proxies.getUnproxyableClassException(Proxies.java:217)
at org.jboss.weld.util.Proxies.getUnproxyableTypeException(Proxies.java:178)
Run Code Online (Sandbox Code Playgroud)
但是,我在类上确实有一个可注入的构造函数:
@Inject
public Config(ConfigLocator configLocator) {
defaultConfigPath = configLocator.getPath();
doStuff();
}
Run Code Online (Sandbox Code Playgroud)
使用默认构造函数,变量注入和postconstruct方法,这些都可以正常工作,但是在这种情况下,我更喜欢使用构造函数注入。
有什么想法怎么了?
这可能是一个愚蠢的问题,但我很困惑,我无法在任何地方找到任何明确的解释.
HK2是一个实现JS330的依赖注入框架,它是Glassfish V3和V4的基础.据我所知,泽西岛使用它
Weld是CDI的参考实现,它也是一个依赖注入框架,也可以在Glassfish中使用?
所以我的问题是这些
我理解这些问题源于我对Java EE整个生态系统的微薄理解,但我们将非常感谢任何答案
我有一个Wildfly 8.2.0.Final应用服务器使用full-ha配置文件在域模式下运行集群.该集群由两个wildfly,master和slave实例组成,每个实例都在自己的虚拟机上运行.
我的项目在应用程序服务器上部署为war-file.出于测试目的,我的负载均衡器使用循环法分配请求.
匿名用户可以使用按钮来使用此项目提供的服务,该按钮将首先调用两个步骤然后登录.登录将使用在注册阶段创建的会话,提供在注册调用期间创建的凭据.
登录端点是请求范围的CDI bean,其中包含保存用户信息的成员.用户信息是SessionScopped EJB Bean,它在会话实例化期间创建,并注入到登录端点CDI bean中.用户信息应该在集群成员之间分配.
现在有趣的部分:
在我的项目中,我在持久层中使用JSF + JPA + CDI + WildFly 8.2.我有一个BasicDao,像这样:
public class BasicDao<M, K> {
private org.jboss.logging.Logger logger = org.jboss.logging.Logger
.getLogger("BasicDao");
@Inject
@Primary
protected EntityManager em;
Class<M> mclass;
public EntityManager getEm() {
return em;
}
public void setEm(EntityManager em) {
this.em = em;
}
@Transactional(value=TxType.NOT_SUPPORTED)
public M find(K id){
return em.find(mclass, id);
}
@Transactional(value=TxType.REQUIRED)
public void insert(M inst){
this.em.persist(inst);
}
@SuppressWarnings("unchecked")
@Transactional(value=TxType.REQUIRED)
public K insertWithAutoId(M inst){
this.em.persist(inst);
return (K) this.em.getEntityManagerFactory().getPersistenceUnitUtil().getIdentifier(inst);
}
@Transactional(value=TxType.REQUIRED)
public M update(M updated){
return this.em.merge(updated);
}
@Transactional(value=TxType.REQUIRED)
public void …Run Code Online (Sandbox Code Playgroud) 我的配置是:Wildfly 8.2.0,Weld
是否可以在bean中注入,而不是在CDI的接口中注入?
@Stateless
class Bean implements IBean {
...
}
interface IBean {
...
}
@SessionScoped
class Scoped {
@Inject
Bean bean; //Fail
@Inject
IBean iBean; //OK
}
Run Code Online (Sandbox Code Playgroud)
编辑:
我在上一个问题中的更多信息: 无状态EJB实现接口注入失败