3

我正在尝试在 java SE 中建立一个非常简单的焊接实现。

我有扩展类:

public class MyExtension implements Extension {

    void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd) {
        System.out.println("Starting scan...");
    }      
    <T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> annotatedType, BeanManager beanManager) {
        System.out.println("Scanning type: " + annotatedType.getAnnotatedType().getJavaClass().getName());
    } 
    void afterBeanDiscovery(@Observes AfterBeanDiscovery abd) {
        System.out.println("Finished the scanning process");
    }

    public void main(@Observes ContainerInitialized event) {
        System.out.println("Starting application");
        new Test();
    }
}

然后我有一个要注入的简单类:

public class SimpleClass {
    public void doSomething() {
        System.out.println("Consider it done");
    }
}

最后是我想注入的类:

public class Test {

    @Inject
    private SimpleClass simple;

    @PostConstruct
    public void initialize() {
        simple.doSomething();
    }

    @PreDestroy
    public void stop() {
        System.out.println("Stopping");
    }
}

结果输出是:

80 [main] INFO org.jboss.weld.Version - WELD-000900 1.1.10 (Final)
272 [main] INFO org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
Starting scan...
Scanning type: test.Test
Scanning type: test.SimpleClass
Scanning type: test.MyExtension
640 [main] WARN org.jboss.weld.interceptor.util.InterceptionTypeRegistry - Class 'javax.ejb.PostActivate' not found, interception based on it is not enabled
640 [main] WARN org.jboss.weld.interceptor.util.InterceptionTypeRegistry - Class 'javax.ejb.PrePassivate' not found, interception based on it is not enabled
Finished the scanning process
Starting application

我希望在构造 Test() 时注入简单的类,并调用应该输出预期文本的 postconstruct 方法。

我到底做错了什么?

4

3 回答 3

5

您的代码有两个问题:

问题1

CDI 不管理使用new. 在大多数情况下,您需要 @Inject 一个 bean 以便其生命周期由容器管理

问题2:

在大多数情况下,您不能将 bean 实例注入到容器事件的观察者中。这是因为事件在容器初始化时触发,也就是在它可以实际开始管理对象生命周期之前。

您可以将容器初始化程序观察者直接挂接到您的 Test 类中。像这样的东西:

public class SimpleClass {
    public void doSomething() {
        System.out.println("Consider it done");
    }

   @PostConstruct
    public void initialize() {
        System.out.println("Starting");
    }

    @PreDestroy
    public void stop() {
        System.out.println("Stopping");
    }
}

public class Test {

    @Inject
    private SimpleClass simple;

    public void main(@Observes ContainerInitialized event) {
        System.out.println("Starting application");
        simple.doSomething();
    }       
}
于 2013-01-25T11:58:17.157 回答
0

你做错了什么是打电话new Test()。这构造了一个新的 Test 实例,但在 CDI 的后面。为了让 CDI 注入您的测试实例,CDI 必须自己创建它。

请参阅文档以了解如何在 Java SE 环境中增强 Weld

于 2013-01-25T12:03:59.963 回答
0

使用 @ApplicationScoped 创建一个 utils 类。这个类可以产生各种类型的对象。在您的情况下,就像这样:

@Produces
static SimpleClass generateSimpleClass(){
return new SimpleClass();
}

否则,如果您的 simpleclass 将成为应用程序中的唯一类,请将其类设置为 @ApplicationScoped。问题是如果既没有注解也没有生产者,weld 不知道该类属于容器

于 2013-02-15T13:45:15.600 回答