Because I am constantly busy working on something, I have never had time to actually put everything in words and pictures. But, since you got here, then you must have already seen some part of my work - and this is the way I’m talking. I'm 24, born in Romania, studied at UPG Romania in software development field. I started from 0, mostly with basic stuff, and I’m evolving every day to an expert. I'm focused on freelancing projects, from small websites, to really heavy stuff.

Sunday, May 1, 2011

Injection into producer methods


The implementations of strategies are instantiated using the Java new operator – this means that they will not support dependency injection and interceptors. If you want to avoid these limitations, then you can use dependency injection into the producer method to obtain bean instances:

@Produces @CommandQualifier @SessionScoped public CommandStrategy
generateCommandStrategy(SingleCommandStrategy scs, MultipleCommandStrategy mcs,
CustomCommandStrategy ccs, BasicCommandStrategy bcs) {
switch (nr) {
case 1:
return scs;
case 2:
return mcs;
case 3:
return ccs;
default:
return bcs;
}
}

Even so, this is still not a very pleasant solution - in this case, you must by extra careful with the producer method scope and the injected bean scope. Per example, if SingleCommandStrategy is in @RequestScoped, that will interfere with the producer method scope, which is @SessionScoped and will result into a scopes issue. You can fix this by changing the scope of the producer method to @Dependent or @RequestScoped or even better, use the @New qualifier annotation:

@Produces @CommandQualifier @SessionScoped public CommandStrategy
generateCommandStrategy(@New SingleCommandStrategy scs, @New
MultipleCommandStrategy mcs, @New CustomCommandStrategy ccs, @New
BasicCommandStrategy bcs) {
switch (nr) {
case 1:
return scs;
case 2:
return mcs;
case 3:
return ccs;
default:
return bcs;
}
}

Well, that is much better! Now, a new dependent instance of each implementation will be created, passed and returned by the producer method. At the end, the instance will be associated with the session context and will “survive” until the session is destroyed.

Producer method scope


When no scope is specified, the scope defaults to @Dependent, therefore is possible that each session to have multiple instances of the same producer method. It is very important to keep in mind that a producer method does not inherit the scope of the bean that declares the method. The scope of the bean determines the lifecycle of the object upon which the producer method is invoked, while the producer method can have its own scope, which indicates how often the method will be called. Per example, a method producer scoped with @SessionScoped will be called only once on a session time and the declaration look like below:

@Produces @CommandQualifier @SessionScoped public CommandStrategy
generateCommandStrategy() { …

In the same manner, you can apply the CDI accepted scopes.

Working with disposer methods


When a producer method returns objects that requires explicit destruction (database connections, sockets, I/O and so on) you can take advantage of disposer methods. These methods must have at least one parameter, annotated @Disposes, with the same type and qualifiers as the producer method. Per example, a producer method may look like below:

@Produces @SomeConnectionQualifier Some_Connection connect() {
return create_some_connection();
}

If the Some_Connection needs explicit destruction, you can write a disposer method:

void close_some_connection(@Disposes @SomeConnectionQualifier Some_Connection connection) {
connection.close();
}

The disposer method is automatically called with the object produced by the producer method when the context is out of scope.

Note: For additional parameters (beside the Some_Connection), the container will look for a bean that satisfies the type and qualifiers of each parameter and pass it to the method automatically.