Java 焊接不是注射

Java 焊接不是注射,java,weld,Java,Weld,我试图在JavaSE中建立一个非常简单的weld实现 我有扩展课程: public class MyExtension implements Extension { void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd) { System.out.println("Starting scan..."); } <T> void processAnnotatedType(

我试图在JavaSE中建立一个非常简单的weld实现

我有扩展课程:

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 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方法,该方法应输出预期文本


我到底做错了什么

您的代码有两个问题:

问题1

CDI不管理使用
new
创建的bean。在大多数情况下,您需要@injecta bean,以便容器管理其生命周期

问题2:

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

您可以将容器初始值设定项观察器直接挂接到测试类中。大概是这样的:

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();
    }       
}
@Produces
static SimpleClass generateSimpleClass(){
return new SimpleClass();
}

您所做的错误是调用
newtest()
。这构造了一个新的Test实例,但位于CDI的后面。为了让CDI注入您的测试实例,CDI必须自己创建它


请参阅。

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

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();
    }       
}
@Produces
static SimpleClass generateSimpleClass(){
return new SimpleClass();
}

否则,如果simpleclass在应用程序中是唯一的类,请将其类设置为@ApplicationScoped。问题是,如果既没有注释也没有生产者,weld就不知道该类属于容器,所以基本上……要在某些地方使用CDI,您必须在任何地方都使用它?嗯。您必须在每个具有注入依赖项的bean中使用它。这意味着,如果您将这样一个bean捆绑到另一个对象中,该对象也必须由CDI管理(或者原始bean依赖项不会被注入)。这一要求可能导致使用CDI“无处不在”,或者至少比最初设想的对象更多。顺便说一句,我在回答中包括了一些代码示例。