当前位置: 首页 > 知识库问答 >
问题:

如何从父类路径使用CDI托管bean

范楚
2023-03-14

我正在用CDI开发一个库。这个很好用。但是,当我试图将这个库用作项目中包含的Jar时,CDI抱怨说它无法解决对父项目中定义的托管bean的依赖关系。

MyProject-MyLib。jar-MyManagedBean

所以MyLib需要注入一个带有原型@foo注释的bean。此原型应用于MyManagedBean。

@foo
public class MyManagedBean {
    //...
}

我加了豆子。我的父项目也使用xml。但好像有两个不同的CDI容器,MyLib无法访问MyProject。

有什么建议吗?

共有1个答案

袁安志
2023-03-14

我可以使用CDI扩展名访问父类文件。文件和反思。

这是我使用的代码:

public class ConfigExtension implements Extension {

void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) {
    Reflections reflections = new Reflections("");
    Set<Class<?>> types = reflections.getTypesAnnotatedWith(Tester.class);
    types.remove(info.scandi.fusion.cucumber.Tester.class);
    types.addAll(reflections.getTypesAnnotatedWith(Driver.class));
    types.addAll(reflections.getTypesAnnotatedWith(Worker.class));

    types.forEach(type -> {
        abd.addBean(new FusionBean((Class<T>) type, bm));
    });
}

}

public class FusionBean<T> implements Bean<T>, Serializable, PassivationCapable {

/**
 * 
 */
private static final long serialVersionUID = 1L;
private InjectionTarget<T> it;
private Class<T> bean;
private BeanManager bm;

public FusionBean(Class<T> workerClass, BeanManager bm) {
    this.bm = bm;
    bean = workerClass;
    AnnotatedType<T> at = bm.createAnnotatedType(bean);
    // use this to instantiate the class and inject dependencies
    it = bm.createInjectionTarget(at);
}

@Override
public T create(CreationalContext<T> creationalContext) {
    T instance = it.produce(creationalContext);
    it.inject(instance, creationalContext);
    it.postConstruct(instance);
    return instance;
}

@Override
public void destroy(T instance, CreationalContext<T> creationalContext) {
    it.preDestroy(instance);
    it.dispose(instance);
    creationalContext.release();
}

@Override
public Set<Type> getTypes() {
    Set<Type> types = new HashSet<>();
    //Use Apache Common Lang to get all Interfaces and Superclasses
    types.addAll(ClassUtils.getAllInterfaces(bean));
    types.addAll(ClassUtils.getAllSuperclasses(bean));
    return types;
}

@Override
public Set<Annotation> getQualifiers() {
    Set<Annotation> annotations = new HashSet<>();
    for (int i = 0; i < bean.getAnnotations().length; i++) {
        Class<? extends Annotation> possibleQualifier = bean.getAnnotations()[i].annotationType();
        if (bm.isQualifier(possibleQualifier)) {
            annotations.add(bean.getAnnotations()[i]);
        }
    }
    return annotations;
}

@Override
public Class<? extends Annotation> getScope() {
    for (int i = 0; i < bean.getAnnotations().length; i++) {
        Class<? extends Annotation> possibleScope = bean.getAnnotations()[i].annotationType();
        if (bm.isStereotype(possibleScope)) {
            for (Annotation annotation : possibleScope.getAnnotations()) {
                if (bm.isScope(annotation.annotationType())) {
                    return annotation.annotationType();
                }
            }
        }
    }
    return null;
}

@Override
public String getName() {
    return bean.getName();
}

@Override
public Set<Class<? extends Annotation>> getStereotypes() {
    Set<Class<? extends Annotation>> stereotypes = new HashSet<>();
    for (int i = 0; i < bean.getAnnotations().length; i++) {
        Class<? extends Annotation> possibleStereotype = bean.getAnnotations()[i].annotationType();
        if (bm.isStereotype(possibleStereotype)) {
            stereotypes.add(possibleStereotype);
        }
    }
    return stereotypes;
}

@Override
public boolean isAlternative() {
    for (int i = 0; i < bean.getAnnotations().length; i++) {
        if (bean.getAnnotations()[i].equals(Alternative.class)) {
            return true;
        }
    }
    return false;
}

@Override
public Class<?> getBeanClass() {
    return bean.getClass();
}

@Override
public Set<InjectionPoint> getInjectionPoints() {
    return it.getInjectionPoints();
}

@Override
public boolean isNullable() {
    return false;
}

@Override
public String getId() {
    return UUID.randomUUID().toString();
}

}

诀窍是CDI扩展可以访问父类路径。在这里,我使用反射api获取使用我的框架的用户可以指定的Tester、Driver和Worker类。

 类似资料:
  • 首先,我不完全确定这是正确的问题。基本上,我的最终目标是生成一个可以操作一组。docx文件的程序,以便对每个文件进行小的更改。在我看来,docx4j是实现这一目标的最佳方式。但是,我从来没有使用过提供的库之外的库。我首先试图破译手册中提供的所有信息,然后告诉我需要SLF4J才能使用Docx4J。 从这一点来看,我想我做错了什么。我很确定我知道我想写的程序背后的伪逻辑,但我不确定如何写它。我还没有做

  • 我很难在一个使用JSF 2、Facelets和CDI的(非常简单的)WAR项目中获得一个通用的错误页面。 我的应用服务器是WebLogic12c,它应该支持所有这些现成的功能,但它无法显示错误页面。当我将完全相同的WAR部署到Glassfish应用程序服务器时,它可以工作。 我倾向于指责WebLogic在CDI部门存在缺陷,但可以使用一些额外的专业知识来检查我的方法是否错误。 以下是我的应用程序试

  • 我正计划将一个web应用程序从使用JSF托管bean转换为使用CDI托管bean。我知道我需要做以下工作: 在WEB-INF中添加空beans.xml文件。 将所有JSF@ManagedBean替换为CDI@Named Annotations。 用CDI或OmniFaces作用域注释替换所有JSF作用域注释。 将所有JSF@ManagedProperty替换为CDI@Inject Annotati

  • 我想从方法中检索注释(自定义编写的注释)。通常我可以通过访问 但是如果bean由CDI容器管理(我使用的是OpenWebBeans),那么类在运行时会得到增强。然后我必须使用超类来请求注释。目前,我试图通过在类名中查找“$$”来检测是否管理该类。但对我来说,这似乎是一个非常肮脏的解决方案。 有什么好方法可以从CDI管理的bean中检索注释吗? 详细地说,我的代码是这样的:我创建了一个注释“Cool

  • 我有一些cdibean。以前,它们都是JSF管理的bean(从JSF管理的bean更改为CDI管理的bean)。 我像下面这样做是为了删除用户成功下在线订单后管理的一些会话范围的JSF。 以便在订单处理完成后将所有内容设置为默认值。这与在订单处理成功终止后不能注销用户的整个HTTP会话的销毁/无效无关。 与JSF托管bean不同,CDIBean通过一些CDI管理器实现(如Weld)存储到服务器内存

  • 问题内容: 我正在尝试制作Java RMI客户端/服务器应用程序。我在启动应用程序服务器端时遇到问题,因为在我尝试启动应用程序服务器端时,在调用Registry.bind()方法期间,它一直运行在 ClassNotFoundException 中。 我从这里的简单教程开始:http : //docs.oracle.com/javase/1.5.0/docs/guide/rmi/hello/hell