我正在尝试在java中设置一个非常简单的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 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方法。
我到底做错了什么?
发布于 2013-01-25 19:58:17
你的代码有两个问题:
问题1
CDI不管理使用new创建的bean。在大多数情况下,您需要@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-25 20:04:00
您所做的错误就是调用new Test()。这将构造一个新的Test实例,但位于CDI的后面。为了让CDI注入Test实例,CDI必须自己创建它。
参见the documentation for how to boostrap Weld in a Java SE environment。
发布于 2013-02-15 21:45:16
使用@ApplicationScoped创建一个utils类。这个类可以生成每种类型的对象。在您的示例中,就像这样:
@Produces
static SimpleClass generateSimpleClass(){
return new SimpleClass();
}否则,如果您的simpleclass将成为应用程序中的唯一类,请将其类设置为@ApplicationScoped。问题是,如果既没有注释也没有生成器,weld就不知道类属于容器
https://stackoverflow.com/questions/14521232
复制相似问题