If you read the blog entry about migrating to @Named annotation you might wonder how you would migrate your @ManagedProperty annotations.
Since CDI is a specification on its own, it does not deal with JSF specific artifacts. However with very little work you can have a very similar setup.
First we define our own custom annotation @ManagedProperty
package test.managedproperty;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.enterprise.util.Nonbinding;
import javax.inject.Qualifier;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface ManagedProperty {
@Nonbinding String value() default "";
}
Next we define a producer method that knows about our own @ManagedProperty annotation
package test.managedproperty;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;
public class ManagedPropertyProducer {
@Produces @ManagedProperty("") @Dependent
public String getStringManagedProperty(InjectionPoint injectionPoint) {
return (String) getObjectManagedProperty(injectionPoint, String.class);
}
private Object getObjectManagedProperty(InjectionPoint injectionPoint, Class expectedType) {
String value = injectionPoint.getAnnotated().getAnnotation(ManagedProperty.class).value();
FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
ExpressionFactory ef = application.getExpressionFactory();
ELContext elContext = context.getELContext();
ValueExpression ve = ef.createValueExpression(elContext, value, expectedType);
return ve.getValue(elContext);
}
}
Third we use it
@Inject
@ManagedProperty("#{param.param1}")
private String param;
public String getParam() {
return param;
}
public String getParam() {
return param;
}
Note this particular implementation only allows you to have @ManagedProperty fields that are Strings, and this is because the producer methods are safely typed.
Posted November 1, 2013