在CDI中管理非托管bean

在这些(当之无愧的)假期期间,我从事了一个我的宠物项目,该项目在Weld实现中使用CDI ,在Logback实现中使用SLF4J。

问题的术语非常简单:希望将应用程序的日志显示在Swing表中, Logback附加程序必须写在表中。 该表是用CDI管理的,但附加程序却不是:这并不奇怪,因为许多老一代框架都具有自己的生命周期管理。 在JEE6之前的Servlet,Log4J附加程序,Struts操作都有其自己的生命周期管理,与CDI完全无关。 更糟糕的是,依赖注入框架在很大程度上彼此不兼容(想到了Spring),并且需要一个适配器来在它们的上下文之间架起桥梁,因此这种用例是常见的。

我的第一个线索是自己引导Logback,但由于Weld在后台使用SLF4J,所以我找不到办法。 一段时间后,得出的结论是CDI无法提供将我的托管表注入Logback附加程序的方法。 那是一个可悲的结论,但我并没有就此止步:当规范不能满足您的需求时,请跳到实施(但要re悔...)。

Weld有一个很好的补充模块,称为Weld Extensions ,提供了JSR中未提及的其他功能。 请注意,Weld Extensions似乎已被Seam Solder代替,但逻辑保持不变:获取对BeanManager的引用,并通过它强制将表插入到附加器中。

在扩展中,通过Extension标记接口进行回调。 此类扩展由Weld使用服务提供商机制查找。 如果您不熟悉它,请看一下它,它在许多用例中都是优雅而有用的。 因此,我创建了META-INF / services / javax.enterprise.inject.spi.Extension文件。

现在,让我们看一下扩展本身:

importjava.util.List;
importjavax.annotation.PostConstruct;
importjavax.enterprise.context.spi.CreationalContext;
importjavax.enterprise.event.Observes;
importjavax.enterprise.inject.spi.AnnotatedType;
importjavax.enterprise.inject.spi.BeanManager;
importjavax.enterprise.inject.spi.Extension;
importjavax.enterprise.inject.spi.InjectionTarget;
importorg.jboss.weld.environment.se.events.ContainerInitialized;
importorg.slf4j.impl.StaticLoggerBinder;
importch.qos.logback.classic.Logger;
importch.qos.logback.classic.LoggerContext;
importch.qos.logback.classic.spi.ILoggingEvent;
importch.qos.logback.core.Appender;

publicclassLogbackWeldExtensionimplementsExtension{ (1)

  publicvoidbind(@ObservesContainerInitializedevent,BeanManagermanager){ (2)

    LoggerContextloggerContext=(LoggerContext)StaticLoggerBinder.getSingleton().getLoggerFactory();
    Listloggers=loggerContext.getLoggerList();

    for(Loggerlogger:loggers){
      Appenderappender=logger.getAppender("Table"); (3)
      if(appender!=null){
        AnnotatedTypetype=manager.createAnnotatedType(appender.getClass());
        InjectionTargettarget=manager.createInjectionTarget(type);
        CreationalContextcreationalContext=manager.createCreationalContext(null); (4)
        target.inject(appender,creationalContext);
      }
    }
  }
}
  1. 我们继承自Extension
  2. 我们观察到容器初始化事件,这意味着在初始化Weld上下文时调用该方法。 注意, BeanManager是第二个参数,并由框架自动注入!
  3. 我们使用Logback的API来获取非托管附加程序的句柄。 请注意,我们得到的是名称的引用,之所以这么做是因为当时我很懒...将来的版本将浏览所有的附加程序,并按类名获取正确的引用。
  4. 我们使用Weld的API将非托管记录器注入需要它的bean。 注意,这里没有对注入的表bean的引用,如果对托管bean进行了正确的注释,则只是标准DI。 如果您使用此代码,还请注意编译器会警告您有关未使用的泛型(使用它们会很麻烦!)。

而已!

翻译自: https://blog.frankel.ch/managing-unmanaged-beans-in-cdi/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值