在 CDI 容器中手动注册类

2022-09-03 01:35:27

我有一组通过反射实例化的类,因此这些类不是由CDI容器管理的,并且上下文不会进行注入。我的问题是,有没有办法在CDI上下文中注册这些类,以便这些类由上下文管理?

波纹管,是我创建类的方式:

String clazz = "org.myorg.thisIsMyClass";
MyClass myClass = Class.forName(clazz).newInstance(); // myClass instance not managed by CDI

如何使 实例由 CDI 容器管理?myClass


答案 1

如果您的类被容器注册为 Bean,则可以使用编程查找来轻松获取它们。

@Inject
@Any
Instance<Object> myBeans;

public Object getMyBeanFromClassName(String className) throws Exception{    
    Class clazz = Class.forName(className);
    return myBeans.select(clazz).get();  
}

Et voilà.


答案 2

根据@AdrianMitev的评论,我最终编写了这个类,它返回一个托管CDI Bean的实例,给定其类名(elName)或类类型:

public class GetInstance {
    public static Object of(String elName) {
       BeanManager bm = getBeanManager();
       Bean<?> bean = bm.resolve(bm.getBeans(elName));
       return bm.getReference(bean, bean.getBeanClass(), bm.createCreationalContext(bean));
    }

    @SuppressWarnings("unchecked")
    public static <T> T of(Class<T> clazz) {
        BeanManager bm = getBeanManager();
        Bean<?> bean = bm.resolve(bm.getBeans(clazz));
        return (T) bm.getReference(bean, bean.getBeanClass(), bm.createCreationalContext(bean));
    }

    private static BeanManager getBeanManager() {
        try {
            return (BeanManager) new InitialContext().lookup("java:comp/BeanManager");
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

所以,如果你有一个像这样的类:

@Named
public class FooClass {
...
}

您可以使用以下命令获取托管 CDI 实例:

FooClass fC = GetInstance.of(FooClass.class);

或使用其elName

FooClass fC = (FooClass) GetInstance.of("fooClass");

或者您可以选择要使用的名称:

@Named(value="CustomFooClassName")
public class FooClass {
...
}

并使用:

FooClass fC = (FooClass) GetInstance.of("CustomFooClassName");

推荐