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