标签: cdi

JAVA EE代理模式

我一直在阅读,当你要求在bean中注入依赖项时,你会向该资源的一个实例注入一个代理.我相信我知道代理是什么,它是一个知道如何将消息转发到另一个实例的实例.它还声明,正是这种模式允许容器为这个托管bean提供服务.

我不太了解这一点.为什么需要代理?这是如何实现的?每个bean都有一个代理对象吗?或者我有很多代理转发到一个实例?或者两者都不是?

另外,根据GoF的书籍设计模式,我已经读过你必须提供一个充当占位符的代理类.但我从来没有在Java EE中这样做,应用服务器是否在运行时创建代理类?

dependency-injection java-ee cdi proxy-pattern

3
推荐指数
1
解决办法
1659
查看次数

具有扩展持久性上下文的有状态EJB,用于处理用户会话

我正在使用CDI会话范围bean来保存用户相关信息(他的用户实体bean,凭证等).每次用户更改其信息(如电子邮件,密码等)时,我都有一个保存方法.但是,我可以使用具有扩展持久性上下文的有状态会话bean来执行此操作.如果我这样做,他的用户实体将在他的会话期间被管理,并且他的电子邮件等的更改将被同步而不重新创建持久性上下文等.这是一个好主意吗?我应该有一个扩展的持久化上下文打开这么久吗?这也锁定了外部bean对用户的更改吗?如果我有管理员尝试对此用户进行更改(可能会发生),该怎么办?

java jsf ejb jpa cdi

3
推荐指数
2
解决办法
1829
查看次数

Hibernate代理继承问题

我正在使用每个具体类的继承策略表,今天我遇到了一些非常奇怪的事情.我仍然不知道这个问题的原因,但让我解释它是什么...

我有以下课程:

@Entity
@Table(name="...")
@Inheritance(strategy=InheritanceType.JOINED)
public class A implements Serializable{...}

@Entity
@Table(name="...")
@PrimaryKeyJoinColumn(name="...")
public class B extends A{...}
Run Code Online (Sandbox Code Playgroud)

看起来很简单,我用来检索条目的查询基本上是这样的:

FROM A
Run Code Online (Sandbox Code Playgroud)

这也返回B的实例,这是我所期望的.这些条目被加载到视图的支持bean中(Bean是视图编组的,持久化上下文已经结束).视图通过EL访问bean以检索dataTable的条目:

<h:dataTable value="#{bean.entries}" var="entry">...</h:dataTable>
Run Code Online (Sandbox Code Playgroud)

在dataTable中,我有一个这样的commandLink:

<h:commandLink value="click" actionListener="#{bean.doSomething}">
    <f:setPropertyActionListener value="#{entry}" target="#{bean.selected}" />
</h:commandLink>
Run Code Online (Sandbox Code Playgroud)

bean使用类型A的对象,但是如果所选条目的类型是子类,则在调用actionListener-Expression时调用的CDI-Decorator会执行其他操作:

public void doSomething(ActionEvent event){
    if(delegate.getSelected() instanceof B){
        // special
    }else{
        delegate.doSomething(event);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在它变得复杂了.if是"有时"输入但不是在预期时输入.调试显示返回的Object delegate.getSelected()是类型的A_javassisst,当它应该是B的实例时.最好的事情是,toString()方法返回B @ 123让我相信第一个地方,即对象属于B型,但不是......

现在我们来问我的问题......到底发生了什么?我已经考虑过在保存dataTable的状态时可能会出现的一些序列化问题,但我不确定(数据表是否应该检索value-expression返回的值并使用这些值进行遍历或者可能会中断国家?).

dataTable是一个PrimeFaces数据表,没有尝试过JSF数据表,但它不能成为primefaces的错...

所有这些都在以下环境中:

  • WAS 8.0.0.1(=> OpenWebBeans)
  • CODI 1.1.1
  • MyFaces 2.1.1
  • Hibernate 3.6.5

在此先感谢您的帮助!

编辑:

我的所有对象都是B类,意味着db在表"b"中包含表"a"中每个条目的条目,但有时我从JPA/Hibernate返回的对象不是B的实例!我需要帮助,我不知道为什么会发生这种情况!?!

编辑:

我的诊断错了,返回的类型是正确的!我真的有一个类型B的代理,而不是类型A的代理.我的问题是在setter之前调用了装饰的方法.这比Hibernate更多的JSF相关!

我没有遇到你报告的问题和陷阱,使用instanceof对我来说很好!

hibernate jpa cdi

3
推荐指数
1
解决办法
3900
查看次数

CDI bean构造函数和@PostConstruct多次调用

经过一些实验,这在使用CDI bean时似乎是一个问题,而与PrimeFaces无关,这是我最初的假设.

如果我使用@ManagedBean将TableBeanLazy更改为Managed Bean,那么构造函数和@PostConstruct方法只会被调用一次,正如我所期望的那样.

任何人都可以对此有所了解吗?

================================================== =

我是JSF和PrimeFaces的新手,所以任何指导都将非常感谢.我搜索了其他帖子,并阅读了一些类似的帖子,但找不到解决方案.

我试图在我的项目中的PrimeFaces Showcase站点上获取延迟加载数据表示例,但由于bean类的行为不像我期望的那样,我遇到了问题.

我对PrimeFaces站点的示例代码进行了一些更改: - 将TableBean类重命名为TableBeanLazy; 在课堂上添加了注释; 分配静态字符串数组; 将初始化从构造函数移动到@PostConstruct initialise()方法; 分配了汽车成员变量.

我还在构造函数和@PostConstruct方法中添加了跟踪消息,这些消息显示在第一次显示表时多次调用它们,每次单击搜索图标时多次调用,并且多次使用每个字符条目过滤领域.

这导致每次执行操作时都会重新创建Car对象的随机列表,因此sort和filter将永远不会产生预期的结果 - 这是在PrimeFaces Showcase站点上直接运行示例时所做的.

虽然我最初使用@ViewScoped,但我也尝试过@RequestScoped,最后是@SessionScoped,但所有行为都是一样的.

多次调用构造函数和@PostConstruct是bean的预期行为?

如果是这样,PrimeFaces Showcase网站上给出的示例代码怎么可能有效呢?

我该如何解决这个问题?

环境

PrimeFaces 3.5
JSF 2.1
JDK 1.7
GlassFish Server Open Source Edition 3.1.2.2 (build 5)
Mojarra 2.1.6 (SNAPSHOT 20111206)
Netbeans IDE 7.3
Windows 7 Pro x64
Run Code Online (Sandbox Code Playgroud)

MyTable.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  template="./resources/templates/platform_tpl.xhtml"
  xmlns:p="http://primefaces.org/ui"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core">

  <ui:define name="body">
    <h2 style="margin-top: …
Run Code Online (Sandbox Code Playgroud)

jsf primefaces cdi

3
推荐指数
1
解决办法
7612
查看次数

如何在加载JSF页面之前在辅助bean中启动特殊的init事件?

PF 3.5.10,Mojarra 2.1.21,Omnifaces 1.5

如何在加载.xhtml JSF页面之前调用特殊的init() - 某些(CDI)SessionScoped bean的方法?现在我调用init(),如果用户从站点菜单中选择页面(带p:menutitem).但是如果用户使用浏览器地址行直接输入url该怎么办?

编辑my.xhtml::

<ui:define template="/mytemp.xhtml">
   <f:event type="preRenderView" listener="#{mybean.init()}" />
   <h:form>
     <p:commandButton update="@form" ... />
   </h:form>
</ui:define>
Run Code Online (Sandbox Code Playgroud)

如果我这样做,init()将在每次更新时调用(即每次回发到服务器),例如每次单击commandButton时.所以我不能使用你的提议.

编辑2:谢谢Luiggi Mendoza和BalusC!除了Luiggi Mendoza的解决方案之外,正如评论所述,Omnifaces 1.6也将拥有ViewScope.

jsf cdi jsf-2

3
推荐指数
1
解决办法
1万
查看次数

JPA和JSF:注入EntityManager的正确方法

已经有几个小时我正在研究这个问题,但我还没弄清楚将JPA与JSF一起使用的正确方法是什么.

我有一个会话范围的托管bean,可以做很多事情,其中​​一个是持久化一些实体对象.最初,我创建了一个生成器方法,请求作用域,构建我的EntityManager对象.无论如何,这里读取将请求的scoped bean注入到会话范围的bean中,将该实例包装到Instance对象中.完成.但是当我尝试使用那个EM时,我得到了一个需要事务的异常.继续在互联网上阅读有人告诉我必须使用PersistenceContext注释将EM直接注入我的托管bean.无论如何,我认为使用persistenceUnit注释更有意义,并在我需要它们的方法中创建我的em.注入工作,但当我试图坚持一些东西时,我仍然得到一个事务所需的异常!

所以我在这里问:这样做的正确方法是什么?

编辑:我正在使用Jboss eap 6.2使用默认设置.我正在使用WEB-INF中的xml文件部署我的数据源,所以我正在使用JTA.

java jsf hibernate jpa cdi

3
推荐指数
1
解决办法
6695
查看次数

通过@ManagedProperty注入ResourceBundle似乎在@Named中不起作用

如何从java代码访问消息包以根据当前区域设置获取消息?

我尝试使用@ManagedProperty如下:

@Named 
@SessionScoped 
public class UserBean implements Serializable {

    @ManagedProperty("#{msg}")
    private ResourceBundle bundle;

    // ...

    public void setBundle(ResourceBundle bundle) {
        this.bundle = bundle;
    }

}
Run Code Online (Sandbox Code Playgroud)

但是,它仍然存在null.它似乎在一个内部不起作用@Named.

这是我在faces-context.xml以下方面注册资源包的方式:

<application>

    <message-bundle>validator.messages</message-bundle>

    <locale-config>
        <supported-locale>en_US</supported-locale>
        <supported-locale>ua_UA</supported-locale>
    </locale-config>

    <resource-bundle>
        <base-name>lang.messages</base-name>
        <var>msg</var>
    </resource-bundle>

</application>
Run Code Online (Sandbox Code Playgroud)

作者的作者:

@BalusC我收到错误

16:29:10,968 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/WEBSearchPrime_JB_lang].[Faces Servlet]] (http-localhost-127.0.0.1-8080-1) Servlet.service() for servlet Faces Servlet threw exception: org.jboss.weld.exceptions.IllegalProductException: WELD-000054 Producers cannot produce non-serializable instances for injection into non-transient fields of passivating beans\\n\\nProducer\: Producer Method [PropertyResourceBundle] with …

jsf resourcebundle cdi

3
推荐指数
1
解决办法
3304
查看次数

CDI:生成scoped bean时获取InjectionPoint

当你的生产者方法生成一个scoped bean时,最简单的获取InjectionPoint的方法是什么?出于某种原因,规范只允许在生成scoped bean时注入InjectionPoint.有没有一种简单的方法可以做到这一点或某种bolg条目或教程?

为了澄清,这是我喜欢做的事情,但规范禁止的是:

@Produces
@RequestScoped
@MyAnnotation    
private MyObject produce(InjectioPoint ip){
....
}
Run Code Online (Sandbox Code Playgroud)

java cdi

3
推荐指数
1
解决办法
1475
查看次数

不调用@PostConstruct的抽象祖先

我正在编写一个JAX-RS库(不是应用程序).

我有:

abstract class A {

    @PostConstruct
    private void constructed_a() {} // not invoked

    @Inject
    private Some some;
}


public abstract class B extends A {

    @PostConstruct
    private void constructed_b() {} // not invoked
}
Run Code Online (Sandbox Code Playgroud)

和测试类:

@Path("c")
public class C extends B {

    @PostConstrct
    private void constructed_c() {} // invoked
}
Run Code Online (Sandbox Code Playgroud)

我正在测试jersey测试框架v2.17

我发现只constructed_c()调用它并且不调用祖先定义的那些方法.请注意,在类中some声明的field()已正确注入.@InjectA

这是正常的吗?我该怎么办?


结论

我使用embedded-glassfish进行了测试,发现正如Antonin Stefanutti指出的那样,这些回调方法按预期顺序调用.

constructed_a()
constructed_b()
constructed_c()
Run Code Online (Sandbox Code Playgroud)

java unit-testing jax-rs jersey cdi

3
推荐指数
1
解决办法
5629
查看次数

CDI Bean和JPA事务

例如,用作cdi应用程序范围的bean是否应包含jpa读/写内容,还是应该对db内容始终使用EJB?我在互联网上的某个地方读到cdi不应包含db内容。真的吗?

java jpa cdi

3
推荐指数
1
解决办法
2147
查看次数