标签: cdi

使用CDI @Inject注入Spring bean

我正在尝试将Spring上下文中定义的bean注入CDI托管组件,但我没有成功.不注入bean,而是每次执行注入时都会创建一个新实例.我的环境是使用JBoss Weld的Tomcat 7.

Spring ApplicationContext是直截了当的:

<beans>
  ...
  <bean id="testFromSpring" class="test.Test" />
  ...
</bean>
Run Code Online (Sandbox Code Playgroud)

CDI托管bean看起来像这样:

@javax.inject.Named("testA")
public class TestA {

  @javax.inject.Inject
  private Test myTest = null;

  ...

  public Test getTest() {
    return this.myTest;
  }

}
Run Code Online (Sandbox Code Playgroud)

这是我的 faces-config.xml

<faces-config 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/web-facesconfig_2_0.xsd" version="2.0">
  <application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
  </application>
</faces-config>
Run Code Online (Sandbox Code Playgroud)

但是,当我test从JSF页面访问该属性时,Test每次访问时都会创建一个新实例.这是一个简单的例子:

<html>
  ...
  <p>1: <h:outputText value="#{testFromSpring}" /></p>
  <p>2: <h:outputText value="#{testA.test}" /></p>
  ...
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

1: test.Test@44d79c75
2: test.Test@53f336eb
Run Code Online (Sandbox Code Playgroud)

刷新后:

1: test.Test@44d79c75
2: test.Test@89f2ac63
Run Code Online (Sandbox Code Playgroud)

我可以看到第一个输出是正确的.无论我多久刷新一次页面,都会testFromSpring返回Spring上下文中定义的bean的值.但是第二个输出清楚地表明,每次调用组件getTest上的方法时test,Test …

java jsf spring cdi jboss-weld

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

EntityListeners中的CDI注入

由于JPA 2.0不支持注入EntityListener(JPA 2.1将),因此决定使用JNDI查找来获取BeanManager并通过它获取登录用户.我定义了一个EntityListener类似的:

public class MyEntityListener {

    public static BeanManager getBeanManager() {
        try {
            InitialContext initialContext = new InitialContext();
            return (BeanManager) initialContext.lookup("java:comp/BeanManager");
        } catch (NamingException e) {
            e.printStackTrace();
            return null;
        }
    }

    public Object getBeanByName(String name) {
        BeanManager bm = getBeanManager();
        Bean bean = bm.getBeans(name).iterator().next();
        CreationalContext ctx = bm.createCreationalContext(bean);
        return bm.getReference(bean, bean.getClass(), ctx);
    }

    @PrePersist
    @PreUpdate
    public void onPreInsertOrUpdate(MyEntity entity) {
        User loggedInUser = (User) getBeanByName("loggedInUser");
        entity.setUpdatedUser(loggedInUser);
        entity.setUpdatedTimestamp(new Date());
    }
}
Run Code Online (Sandbox Code Playgroud)

用户在会话范围内管理为:

@SessionScoped
public class UserManager …
Run Code Online (Sandbox Code Playgroud)

hibernate cdi java-ee-6 jpa-2.0 jboss-weld

10
推荐指数
1
解决办法
6210
查看次数

启动ejb bean不起作用

我正在尝试使用启动ejb在启动时做一些事情.但我的豆子从未被召唤过.

这是我的豆子:

import javax.annotation.PostConstruct;
import javax.ejb.Startup;
import javax.inject.Singleton;

@Singleton
@Startup
public class StartupBean {

    @PostConstruct
    public void doSomething(){
        System.out.println("why??");
    }

}
Run Code Online (Sandbox Code Playgroud)

我正在使用jboss 7.1.1.

我究竟做错了什么?你可以在bitbucket找到我的源代码:https://bitbucket.org/cremersstijn/jee/src/9e22ed2b798a/simple-startup-bean

java jboss ejb cdi

10
推荐指数
1
解决办法
3783
查看次数

如何在生产中使用CDI测试类时注入模拟

我正在使用WELD-SE进行依赖注入的Java SE环境中进行编程.因此,类的依赖关系看起来像这样:

public class ProductionCodeClass {
    @Inject
    private DependencyClass dependency;
}
Run Code Online (Sandbox Code Playgroud)

在为这个类编写单元测试时,我正在创建一个模拟器DependencyClass,因为我不想为我运行的每个测试启动一个完整的CDI环境,我手动"注入"模拟:

import static TestSupport.setField;
import static org.mockito.Mockito.*;

public class ProductionCodeClassTest {
    @Before
    public void setUp() {
        mockedDependency = mock(DependencyClass.class);
        testedInstance = new ProductionCodeClass();
        setField(testedInstance, "dependency", mockedDependency);
    }
}
Run Code Online (Sandbox Code Playgroud)

setField()我使用我在测试中使用的工具在类中编写的静态导入方法:

public class TestSupport {
    public static void setField(
                                final Object instance,
                                final String field,
                                final Object value) {
        try {
            for (Class classIterator = instance.getClass();
                 classIterator != null;
                 classIterator = classIterator.getSuperclass()) {
                try {
                    final Field declaredField …
Run Code Online (Sandbox Code Playgroud)

java unit-testing mockito cdi

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

CDI/Weld:书籍或资源推荐

是否有可以推荐的CDI/Weld现有或即将出版的书籍?

我正在寻找与Seam in Action类似的东西,这是Seam的一个很好的参考,但现在看起来有点过时了.

cdi jboss-weld

9
推荐指数
2
解决办法
3075
查看次数

@SessionScoped如何与EJB一起工作?CDI仅适用于Web层吗?

如何在CDI bean中定义会话@SessionScoped
这个注释是否仅在从Servlet容器调用时才有效,其中会话以HttpSession?的形式定义好?

如果不是,那么EJB如何@Inject @SessionScoped MyBean myBean能够知道会话到底是什么?我的意思是,这个EJB的方法可以由独立客户端,RESTful WS或其他视图调用.
在这种情况下会发生什么?如果注释没有意义,它应该MyBean为每个请求注入新的实例,还是应该在所有请求中保留相同的实例?

session servlets cdi java-ee-6 ejb-3.1

9
推荐指数
1
解决办法
4545
查看次数

CDI:@alternative vs @Qualifiers

作为CDI的新手,我想知道替代品和限定符之间的实际区别.

Weld参考文献中,它声明:

4.3.限定符注释

如果我们有多个实现特定bean类型的bean,则注入点可以使用限定符注释准确指定应注入哪个bean.

但在解释替代品时,据说:

4.7.备择方案

替代方案是bean,其实现特定于特定客户端模块或部署方案.

如果我理解正确,@ Qualifier定义了目标bean的哪些实现被注入到注入点.

另一方面,@ Alternative描述了在部署期间依赖于客户关于标准的Alternatice(我的意思是"@default")是否被注入注入点的愿望.

这是正确的 ?

java dependency-injection cdi

9
推荐指数
1
解决办法
2440
查看次数

Glassfish 4.0中的Bean-Validation 1.1 - CDI注入不按预期工作

根据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输出: …

glassfish java-ee cdi bean-validation

9
推荐指数
1
解决办法
3226
查看次数

如何在PhaseListener中@Inject

我添加了一个PhaseListenerfaces-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

jsf cdi jsf-2 phaselistener

9
推荐指数
1
解决办法
4496
查看次数

构造函数注入vs场注入

注入任何服务时,我有两个选择:

(现场注射)

 @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注射更好?

java dependency-injection cdi sonarqube

9
推荐指数
3
解决办法
6551
查看次数