java 焊缝未注入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14521232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Weld is not injecting
提问by nablex
I'm trying to set up a very simple implementation of weld in java SE.
我正在尝试在 java SE 中设置一个非常简单的焊接实现。
I have the extension class:
我有扩展类:
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();
}
}
I then have a simple class that I want to inject:
然后我有一个要注入的简单类:
public class SimpleClass {
public void doSomething() {
System.out.println("Consider it done");
}
}
And lastly the class I want to inject it in:
最后是我想注入的类:
public class Test {
@Inject
private SimpleClass simple;
@PostConstruct
public void initialize() {
simple.doSomething();
}
@PreDestroy
public void stop() {
System.out.println("Stopping");
}
}
The resulting output is:
结果输出是:
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
I would expect the simple class to be injected when Test() is constructed and the postconstruct method to be called which should output the expected text.
我希望在构造 Test() 时注入简单的类,并调用应该输出预期文本的 postconstruct 方法。
What exactly am I doing wrong?
我到底做错了什么?
回答by Perception
There's two issues with your code:
您的代码有两个问题:
Problem 1:
问题1:
CDI does not manage beans created with new
. For the most part you need to @Inject a bean in order for its life cycle to be managed by the container
CDI 不管理用new
. 在大多数情况下,您需要 @Inject 一个 bean 以便容器管理它的生命周期
Problem 2:
问题2:
For the most part, you cannot inject bean instances into observers of container events. That's because the events are firing as the container is being initialized, aka before it can actually begin managing object life cycles.
大多数情况下,您不能将 bean 实例注入到容器事件的观察者中。那是因为事件在容器被初始化时触发,也就是在它实际开始管理对象生命周期之前。
You could hook the container initializer observer directly into your Test class. Something like this:
您可以将容器初始值设定项观察者直接挂接到您的 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();
}
}
回答by JB Nizet
What you're doing wrong is calling new Test()
. This constructs a new instance of Test, but in the back of CDI. For CDI to inject your Test instance, CDI has to create it itself.
你做错了什么是调用new Test()
. 这构造了一个新的 Test 实例,但是在 CDI 的后面。为了让 CDI 注入您的 Test 实例,CDI 必须自己创建它。
See the documentation for how to boostrap Weld in a Java SE environment.
回答by user1969592
Create a utils class with @ApplicationScoped. This class can produce objects of every type. In your case this is just like this:
使用@ApplicationScoped 创建一个 utils 类。此类可以生成各种类型的对象。在你的情况下,这就像这样:
@Produces
static SimpleClass generateSimpleClass(){
return new SimpleClass();
}
Otherwise, if simpleclass for you is going to be a unique class in the application, set its class as @ApplicationScoped. Problem is that weld does not know that the class belongs to the container if there is neither annotation nor producer
否则,如果您的 simpleclass 将成为应用程序中的唯一类,请将其类设置为 @ApplicationScoped。问题是,如果既没有注解也没有生产者,则焊缝不知道该类属于容器