是否有可以推荐的CDI/Weld现有或即将出版的书籍?
我正在寻找与Seam in Action类似的东西,这是Seam的一个很好的参考,但现在看起来有点过时了.
我正在开发一个Java EE应用程序,主要是带有JSF管理控制台的JAX-RS,它使用CDI/Weld来javax.enterprise.context.ApplicationScoped对象注入依赖项.除了一些小的调试问题,CDI已经为这个项目做了很好的工作.
现在我需要对CDI注入的对象生命周期进行一些非常粗粒度的控制.我需要能力:
@ScopeType并实现Context我可以提供执行上述两个任务之一的方法.我完全清楚,一般来说,如果不是反对的话,CDI和依赖注入都是如此.我只是想知道
如何在CDI bean中定义会话@SessionScoped?
这个注释是否仅在从Servlet容器调用时才有效,其中会话以HttpSession?的形式定义好?
如果不是,那么EJB如何@Inject @SessionScoped MyBean myBean能够知道会话到底是什么?我的意思是,这个EJB的方法可以由独立客户端,RESTful WS或其他视图调用.
在这种情况下会发生什么?如果注释没有意义,它应该MyBean为每个请求注入新的实例,还是应该在所有请求中保留相同的实例?
在JSF 2.0中,视图范围最明显的用例是具有可能多个AJAX回发的单个页面.使用CDI而不是JSF托管bean留给我们不认为范围,使我们要么留下来实现我们自己的,使用(可能充满错误的)第三方实施或使用会话范围.
我的问题:在典型的AJAX情况下,会话范围是否值得替代视图范围?与视图范围一样,它是否允许每个会话多个实例?有什么陷阱?
我知道的陷阱之一,即当用户导航离开页面的谈话范围不会自动删除,而是超时之后被删除.但我不确定当用户在对话超时之前导航回该页面时会发生什么.
UPDATE
会话范围确实支持每个会话多个实例.这本书说明了这一点,我能够使用ch中的代码来证实这一点.2.
作为CDI的新手,我想知道替代品和限定符之间的实际区别.
在Weld参考文献中,它声明:
4.3.限定符注释
如果我们有多个实现特定bean类型的bean,则注入点可以使用限定符注释准确指定应注入哪个bean.
但在解释替代品时,据说:
4.7.备择方案
替代方案是bean,其实现特定于特定客户端模块或部署方案.
如果我理解正确,@ Qualifier定义了目标bean的哪些实现被注入到注入点.
另一方面,@ Alternative描述了在部署期间依赖于客户关于标准的Alternatice(我的意思是"@default")是否被注入注入点的愿望.
这是正确的 ?
根据Glassfish 4.0 wiki,Glassfish 4.0应包含JSR349 Bean Validation 1.1: GF4 wiki链接
根据JSR349规范,CDI Injection应该开箱即用:Bean Validation 1.1.CDI集成
所以我相应地更改了我的pom.xml:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
<scope>provided</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
并尝试将CDI Bean注入ConstraintValidator:
public class UniqueEmaiValidator implements ConstraintValidator<UniqueEmail, String> {
@Inject
private UserAccountService accountService;
@Override
public void initialize(UniqueEmail constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return !accountService.userExistsByEmail(value);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,在测试应用程序(使用arquillian-glassfish-remote-3.1 1.0.0.CR4运行Arquillian 1.1.1.)时,验证将始终失败,因为它userAccountService为null,因此NullPointerException最终会抛出 .
我错过了什么使Bean Validation 1.1工作?
编辑:
A)可以确认它不是由Arquillian远程测试引起的 - 也会抛出NPEx.在服务器上运行时
B)在GlassFish Server Open Source Edition 4.0上运行(build 89)
C)我使用Hibernate Validator的5.0.1.FINAL显式重新构建了bean-validation.jar.的mvn package输出: …
我添加了一个PhaseListener到faces-config.xml:
<lifecycle>
<phase-listener>com.project.NotificationListener</phase-listener>
</lifecycle>
Run Code Online (Sandbox Code Playgroud)
这个类似乎是正确的,因为它非常简单.
public class NotificationListener implements PhaseListener {
@Inject
private MyCDIStuff stuff;
@Override
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
@Override
public void beforePhase(PhaseEvent event) {
this.stuff.doStuff();
}
}
Run Code Online (Sandbox Code Playgroud)
'beforePhase'方法被正确调用,但MyCDIStuff对象为null.我尝试使用@Singleton最可能不正确的类的注释,并且它也没有使注入工作.
有没有办法注入CDI托管bean PhaseListener?
我想使用CDI向JSF Web应用程序中的托管bean注入常量字符串消息,这里是生产者类:
@Named
@RequestScoped
public class StringProducer {
@Produces
@Named("message")
@RequestScoped
public String getMessage() {
return "Hello World";
}
}
Run Code Online (Sandbox Code Playgroud)
以下是它如何在另一个托管bean中注入:
@Inject Named("message") String message;
Run Code Online (Sandbox Code Playgroud)
但这总是导致异常:
org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001435 Normal scoped bean int is not proxyable
Run Code Online (Sandbox Code Playgroud)
我试图在Instance中包装String类型,如下所示:
@Inject Named("message") Instance<String> message;
Run Code Online (Sandbox Code Playgroud)
但没有改变.
我打算将Web应用程序从使用JSF托管bean转换为使用CDI托管bean.我知道我需要在下面做:
是这一切都需要做吗?我需要注意哪些问题?
注入任何服务时,我有两个选择:
(现场注射)
@Inject
private MyService myService;
Run Code Online (Sandbox Code Playgroud)
或(构造函数注入)
private MyService myService;
@Inject
public ClassWhereIWantToInject(MyService mySerivce){
this.myService = myService;
}
Run Code Online (Sandbox Code Playgroud)
为什么Constructor注射比Filed注射更好?