我在理解Weld或CDI的会话范围时遇到了一些问题.
在我的JSF Faclets页面中,我调用:
<f:metadata>
<f:event type="preRenderView" listener="#{viewBean.start}" />
</f:metadata>
Run Code Online (Sandbox Code Playgroud)
豆子:
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
@Named
@ConversationScoped
public class ViewBean implements Serializable {
@Inject
private Conversation conversation;
public void start() {
if (conversation.isTransient()) {
System.out.println("START CONVERSATION");
conversation.begin();
}
}
Run Code Online (Sandbox Code Playgroud)
现在每次刷新浏览器时,都会启动一个新的对话.这是正确的行为吗?那么为什么谈话总是短暂的?没有异常被抛出.beans.xml已创建并为空:
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
Run Code Online (Sandbox Code Playgroud) 我目前正在将一个项目从JBoss 4.2.2迁移到JBoss 6.0.0,我还在使用CDI添加依赖注入,并从JSF 1.2迁移到JSF 2.0.我将一个beans.xml文件添加到ejb-package以及war-package中.
现在我有一个使用托管bean的xhtml页面LoginBean.java.已经在faces-config.xml中配置了bean,如下所示:
<managed-bean>
<description>Sample description</description>
<managed-bean-name>loginBean</managed-bean-name>
<managed-bean-class>com.sample.managedbeans.LoginBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
Run Code Online (Sandbox Code Playgroud)
所以,首先我删除了上面的配置并添加@ManagedBean @SessionScoped到类本身.因为我想CDI添加到项目中,我改变了@ManagedBean对@Named(与质疑2930889).
现在,当我提交相应xhtml的表单时,字段username和password(在JSP中使用#{loginBean.username})为null.当我改回来时@ManagedBean,它工作正常.
我在这里错过了什么吗?
亲切的问候,塞巴斯蒂安
我想向我们的项目介绍CDI(Weld),现在手动构建的对象遇到了一些麻烦.
所以我们有一些实现IReport接口的类,它有一个应该注入的字段.因为所有这些类是由产生这是在运行时零ReportFactory一类ReportController.
private Map<String,Object> generateReport(ReportInfo ri, ...) {
// some input validation
IReport report = ReportControllerFactory.getReportInstance( ri.getClassName() );
// ...
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以将@Produces注释与另一个自定义注释一起使用ReportControllerFactory,但是如何在一个方法中使用@Injectfor只能在完成一些验证之后创建的变量?我将如何提交参数?构造时对象是未知的.ri.getClassName()riReportController
非常感谢你!
亲切的问候,塞巴斯蒂安
编辑于2011年7月8日(10:00):
ReportFactory类:
public static IReport getReportInstance( String className ) throws ReportException {
IReport report = null;
try {
Class<?> clazz = Class.forName( className );
report = (IReport) clazz.newInstance();
}
catch ( Exception e ) { … }
return report; …Run Code Online (Sandbox Code Playgroud) 我有两个Managed Bean:
SessionBean:
@Named(value = "sessionBean")
@SessionScoped
public class SessionBean implements Serializable {
private final Param param
SessionBean(Param param) {
this.param = param;
}
}
Run Code Online (Sandbox Code Playgroud)
和TypesBean:
@Named(value = "typesBean")
@RequestScoped
public class TypesBean {
@Inject
private SessionBean session;
}
Run Code Online (Sandbox Code Playgroud)
该项目将生成,但不会部署:
部署期间发生错误:加载应用程序时发生异常:WELD-001410注入点[field] @Inject私有com.example.TypesBean.session具有不可代理的依赖关系。请参阅server.log以获取更多详细信息。
有什么问题?
我有一个支持bean如下:
@Named
@RequestScoped
public class ClientNewBackingBean {
@Inject
private ClientFacade facade;
private Client client;
Run Code Online (Sandbox Code Playgroud)
本Client类有一个List<Child> childrenList属性,等等.我能够创建一个新的Client设置时childrenList用new ArrayList().
在视图中,我有一个输入文本字段和一个Add Child按钮.该按钮的属性actionListener=#{clientNewBackingBean.addChild()}实现为:
public void addChild() {
if(client.getChildrenList() == null) {
client.getChildrenList(new ArrayList());
}
Child c = new Child("John Doe");
client.getChildrenList().add(c);
}
Run Code Online (Sandbox Code Playgroud)
每次Add Child单击按钮时,都会重新创建bean,并且视图只显示一个John Doe子项(由于它是Request stroped,我相信).除了将bean范围更改为Session之外,还有其他方法可以解决这个问题吗?
我是JSF-2和CDI的新手(我来自Spring世界).
我想从@ManagedBean拦截一个方法,但我的Interceptor类永远不会被调用.有可能吗?
LogInterceptor.java
@Interceptor
public class LogInterceptor {
@AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
System.out.println("begin method interceptor");
Object methodReturn = ctx.proceed();
System.out.println("end method interceptor");
return methodReturn;
}
}
Run Code Online (Sandbox Code Playgroud)
RoleMB
@ManagedBean
@ViewScoped
public class RoleMB extends BaseMB {
@Interceptors(LogInterceptor.class)
public void preEditRole(Role role) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
beans.xml中
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>br.com.preventsenior.services.log.LogInterceptor</class>
</interceptors>
</beans>
Run Code Online (Sandbox Code Playgroud)
将log(InvocationContext ctx)永远不会被调用.
假设我有一个仅产生一些bean,列表,项目等的类
public class MightyProducer {
@Produces
public Bean1 someBean() {
//some init
return new Bean1();
}
@Produces
@CoolItems
public List<Items> items() {
//some init
return new ArrayList<Item>();
}
}
Run Code Online (Sandbox Code Playgroud)
这样的课程应该有什么范围?我应该留给它@Dependent还是最好的方法?我读过CDISingleton对此有好处的地方,但我真的不知道为什么。
我得到了一个如下所示的无状态bean:
@Stateless
public class MyBean implements IMyBean {
@Inject
private SomeClass someClass;
@EJB
private MyRepository myRepository;
@Production
@Inject
private SomeFacade someWorker;
@PostConstruct
private void init() {
// some logic ...
}
// some more logic...
}
Run Code Online (Sandbox Code Playgroud)
IMyBean带有@Local注释。我正在运行JBoss服务器。我得到了一个使用MyBean的.bat文件。仅在第一次执行此bat文件时,才调用@PostConstruct。这是为什么?MyBean属于哪个范围?似乎至少是ApplicationScoped。我以为那是RequestScope ...
我在WildFly 8.2应用服务器中使用JavaEE 7中的Context Dependency Injection CDI 1.1框架
我想@PostConstruct在超类之后初始化子类
所以我做的就像那样
// case 1: it's working but it's not simple to understand
public class A {
@PostConstruct
protected void init() {
System.out.println("A");
afterInit();
}
protected void afterInit() {}
}
public class B extends A {
@Override
protected void afterInit() {
System.out.println("B");
}
}
public class C extends B {
@Override
protected void afterInit() {
super.afterInit();
System.out.println("C");
}
}
Run Code Online (Sandbox Code Playgroud)
因此该init()方法将按此顺序打印A,B,C
如果有一个@AfterPostconstruct注释可以做同样的事情,但我没有找到,这将是很好的
// case 2: dream code
public …Run Code Online (Sandbox Code Playgroud) 我正在使用Payara 4.1.1.161。我有一个Jersey @Path JAX-RS资源,我要做的就是使用CDI @将一个bean注入其中。我已经尝试了许多不同的组合来使其工作,但是到目前为止,我成功使它成功的唯一方法是在beans.xml中设置bean-discovery-mode =“ all”。
我知道“带注释”是没有bean.xml的首选方式。但是,每次尝试使用“带注释的”时,调用JAX-RS资源都会失败,如下所示:
MultiException stack 1 of 1
org.glassfish.hk2.api.UnsatisfiedDependencyException:
There was no object available for injection at
SystemInjecteeImpl(requiredType=InjectMe, parent=InjectResource,
qualifiers={}, position=-1, optional=false, self=false,
unqualified=null, 1000687916))
Run Code Online (Sandbox Code Playgroud)
或者我在部署如下所示的应用程序时遇到了故障:
Exception during lifecycle processing
java.lang.Exception: java.lang.IllegalStateException:
ContainerBase.addChild: start: org.apache.catalina.LifecycleException:
org.apache.catalina.LifecycleException:
org.jboss.weld.exceptions.DeploymentException: WELD-001408:
Unsatisfied dependencies for type InjectMe with qualifiers @Default
at injection point [BackedAnnotatedField]
@Inject private org.thoth.jaspic.web.InjectResource.me
Run Code Online (Sandbox Code Playgroud)
这是我的应用程序设置。
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
Run Code Online (Sandbox Code Playgroud)
JAX-RS应用
@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationResourceConfig extends org.glassfish.jersey.server.ResourceConfig {
public ApplicationResourceConfig() …Run Code Online (Sandbox Code Playgroud) cdi ×10
jsf ×5
java ×4
java-ee ×2
jboss-weld ×2
scope ×2
factory ×1
interceptor ×1
java-ee-6 ×1
jax-rs ×1
jsf-2 ×1
managed-bean ×1
payara ×1
proxy ×1