FacesConverter注入变通方法 - 构造函数替代方案

时间:2013-10-10 19:44:50

标签: jsf cdi inject

这与已知的JSF FacesConverter问题的解决方法无关,因为它不是CDI的合格@Inject目标。我在CDI Injection into a FacesConverter处遵循了解决方法。但是,在我的FacesConverter中,我一直在利用将对象的Class传递给构造函数的功能。

javadoc - “如果转换器具有单个参数构造函数,该构造函数接受一个Class实例并且转换器实例化时已知要转换的数据的类,则必须使用此构造函数来实例化转换器而不是零参数版本。“这与“正常范围”bean的CDI要求直接冲突,其中允许使用no-arg或@Inject带注释的构造函数。

总而言之,我想使用一个可以进行CDI注入的转换器,并且可以访问在运行时转换的对象的类。

我使用Weld 2.0.4在Glassfish 4上使用Mojarra 2.2.4。

1 个答案:

答案 0 :(得分:3)

对于那些可能对这个替代方案感兴趣的人,我能够在构造函数中通过BeanManager将编程注释替换为Inject注释。精简代码如下。我没有经过性能测试,并怀疑这可能是一个缺点。如果时间允许,我将与Omnifaces解决方案进行比较。

编辑:BeanManager查找的成本最低。构造函数平均值<1ms。

@FacesConverter(forClass = AbstractEntity.class)
public class EntityConverter implements Converter {

    private LocationService locationService;
    private Class entityClass;

    //Special parameterized constructor for @FacesConverter described in the original question
    public EntityConverter(Class entityClass) throws NamingException {
            this.entityClass = entityClass;
            this.locationService = loadManagedBean(LocationService.class, "locationService");
        }

    //Generic lookup method for @Named managed beans
    protected <T> T loadManagedBean(Class<T> clazz, String beanName) throws NamingException {
            InitialContext initialContext = new InitialContext();
            BeanManager bm = (BeanManager) initialContext.lookup("java:comp/BeanManager");

            Bean<T> bean = (Bean<T>) bm.getBeans(beanName).iterator().next();
            CreationalContext<T> cc = bm.createCreationalContext(bean);
            T beanInstance = (T) bm.getReference(bean, clazz, cc);
            return beanInstance;
    }
}