In terms of simplicity and correctness, what is the best way to inject objects of the same class with different scopes?
In a servlet I want to have injected objects of the same class with different scopes. Still don't know if going to use jsf.
Qualifier
and a producer method for each scope is too much; making an interface, two classes and adding and alternative in beans.xml
is also too much; having an Address#isCurrent()
method doesn't make sense.@Named
at injection point works with @ApplicationScoped
and
@RequestScoped
but not with @SessionScoped
. See named snippet below.In spring it is very easy:
Spring snippet
<bean id="currentAddress" class="xxx.Address" scope="session" />
<bean id="newAddress" class="xxx.Address" scope="request" />
<bean id="servlet" class="xxx.MyServlet">
<property name="currentAddress" ref="currentAddress" />
<property name="newAddress" ref="newAddress" />
</bean>
named snippet
/* Address class */
@Produces @RequestScoped @Named(value="request")
public Address getNewAddress(){
return new Address();
}
@Produces @SessionScoped @Named(value="application")
public Address getCurrentAddress(){
return new Address();
}
/* Servlet */
@Inject @RequestScoped @Named("request") private Address newAddress;
@Inject @ApplicationScoped @Named("application") private Address currentAddress;
Thanks to @nsfyn55 for pointing out that good article, after reading the section "The Right Way", I came up with what I think is the best way to achieve it in terms of simplicity and correctness.
So I am using only one interface for the qualifier annotation.
/* Qualifier annotation */
@Qualifier
@Retention(RUNTIME)
@Target({FIELD,METHOD})
public @interface Scope {
Type value();
enum Type { REQUEST, SESSION, APPLICATION };
}
/* Address class */
@Produces @Scope(REQUEST) @RequestScoped
public Address request() {
return new Address();
}
@Produces @Scope(SESSION) @SessionScoped
public Address session() {
return new Address();
}
/* Servlet */
@Inject @Scope(REQUEST)
private Address newAddress;
@Inject @Scope(SESSION)
private Address currentAddress;