来自JBoss AS 7.1中动态加载的jar的发现bean

时间:2013-07-03 16:23:12

标签: plugins jboss7.x cdi weld

我的问题 - 有人知道如何在焊接中获取Deployment界面的实例吗?理想情况下,在 beforeBeanDiscovery 事件中?

我正在尝试在我的应用程序中实现插件系统,其中jar由我的war应用程序加载。我正在使用 JBoss AS 7.1

我试图在部署过程中包含JAR,但除非jar在WEB-INF / lib文件夹中,否则似乎不可能。

所以我的下一步是尝试让CDI(Weld)发现外部JAR中的bean。

似乎CDI没有直接支持包含要发现的新jar,但是Weld有一个Deployment接口和一个名为loadDeploymentArchive(http://docs.jboss.org/weld/javadoc/2.0/weld-spi/org/jboss/weld/bootstrap/spi/Deployment.html#loadBeanDeploymentArchive(java.lang.Class))的方法

2 个答案:

答案 0 :(得分:0)

该类用于与应用程序服务器集成。 CDI意味着在启动时为应用程序加载所有内容。要做你正在寻找的东西,你必须启动一个新的Weld实例并传递所有内容并自己进行引导。老实说,我不知道在你的应用程序中这样做的含义,但我可以告诉你,它会给你带来严重的麻烦。

答案 1 :(得分:0)

其实我在http://relation.to/12981.lace

的Gavin King的文章中找到了答案

基本上我必须创建一个扩展并映射afterBeanDiscovery事件,如下所示:

public void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) {
    for ( final Class c: getBeanClasses() ) {

        //use this to read annotations of the class
        AnnotatedType at = bm.createAnnotatedType(c);

        //use this to create the class and inject dependencies
        final InjectionTarget it = bm.createInjectionTarget(at);

        abd.addBean( new Bean() {
            @Override
            public Class<?> getBeanClass() {
                return c;
            }

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

            @Override
            public String getName() {
                String s = c.getSimpleName();
                s = Character.toLowerCase( s.charAt(0) ) + s.substring(1);
                return s;
            }

            @Override
            public Set<Annotation> getQualifiers() {
                Set<Annotation> qualifiers = new HashSet<Annotation>();
                qualifiers.add( new AnnotationLiteral<Default>() {} );
                qualifiers.add( new AnnotationLiteral<Any>() {} );
                return qualifiers;
            }

            @Override
            public Class<? extends Annotation> getScope() {
                return Dependent.class;
            }

            @Override
            public Set<Class<? extends Annotation>> getStereotypes() {
                return Collections.emptySet();
            }

            @Override
            public Set<Type> getTypes() {
                Set<Type> types = new HashSet<Type>();
                types.add(c);
                types.add(Object.class);
                return types;
            }

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

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

            @Override
            public Object create(CreationalContext ctx) {
                Object instance = it.produce(ctx);
                it.inject(instance, ctx);
                it.postConstruct(instance);
                return instance;
            }

            @Override
            public void destroy(Object instance, CreationalContext ctx) {
                it.preDestroy(instance);
                it.dispose(instance);
                ctx.release();
            }

        } );
    }
}

我还必须扫描我的jar用于bean类,但这不是什么大问题。找到类之后,我将其包含在getBeanClasses()列表中。

现在我正在寻找有关如何在运行时包含JPA实体的解决方案。

但到现在为止,这个问题已经解决了。