Reputation: 261
I have a SimpleResource class
@Vetoed
public class SimpleResource {
private String value="TestValue";
public void open(){
System.out.println("Open SR method");
}
public void close(){
System.out.println("Close SR method");
}
public String getValue() {
return value;
}
}
Then I've created a Producer Class
@Singleton
public class EntityManagerProducer {
@Produces
@Default
@Dependent
public static SimpleResource createSimpleResource() {
SimpleResource sr = new SimpleResource();
System.out.println("Open SR");
sr.open();
return sr;
}
public static void disposeSimpleResource(@Disposes @Default SimpleResource simpleResource) {
System.out.println("Close SR");
simpleResource.close();
}
}
And than a Singleton Business class
@Default
@Singleton
public class InjectConstructor {
private String value="init";
@Inject
public InjectConstructor(SimpleResource sr){
value=sr.getValue();
}
public String getValue() {
return value;
}
}
The test method to run
@Test
public void injectConstructor(){
Weld weld = new Weld();
WeldContainer container = weld.initialize();
InjectConstructor inst= container.select(InjectConstructor.class).get();
System.out.println("Value= "+inst.getValue());
}
After runnning test program I've got such response:
INFO org.jboss.weld.Bootstrap - WELD-ENV-002003: Weld SE container STATIC_INSTANCE initialized
Open SR
Open SR method
Value= TestValue
Close Container
Close SR
Close SR method
The problem is that "SimpleResource" is opend before constructor @Inject BUT not close after constructor exited.
The question is How to inject "SimpleResource" through Constructor injection and closed Immediate after constructor exited?
Is the only tecnique to do this is using @Observes method?
public void watchStartup(@Observes @Initialized(ApplicationScoped.class) Object ctxEvent, SimpleResource sr) {
...
}
Upvotes: 2
Views: 499
Reputation: 261
Martin Couba helped me to solve this problem.
you could make use of @javax.enterprise.inject.TransientReference. The producer method for SimpleResource is @Dependent so the disposer method should be called when the invocation of the constructor completes.
@Inject
public InjectConstructor(@TransientReference SimpleResource sr) {
value = sr.getValue();
}
Thank you very much. It is very ellegant solution
Upvotes: 1
Reputation: 11723
Because you're making SimpleResource
dependent, its scope is tied to the lifecycle of the parent, as a result its managed like a singleton. To do what you're looking for, you'd have to make the constructor aware of the bean directly, and perhaps use Unmanaged to create then destroy an instance.
Upvotes: 0