【问题标题】:WELD - exclude application scoped bean from scanning / beans.xmlWELD - 从扫描 / beans.xml 中排除应用程序范围的 bean
【发布时间】:2021-03-18 22:28:30
【问题描述】:

我有以下@ApplicationScoped bean:

@ApplicationScoped
public class ServiceProducer {

    private static final Logger logger = LoggerFactory.getLogger(ServiceProducer.class);

    @Default
    @Produces
    @PersistenceContext(unitName = "nemo")
    private EntityManager nemoEntityManager;

    private CacheManager cacheManager;

    @PostConstruct
    void init() {
        try {
            cacheManager = Caching.getCachingProvider().getCacheManager(
                    Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("/ehcache.xml")).toURI(),
                    Thread.currentThread().getContextClassLoader());
        } catch (URISyntaxException e) {
            logger.error(e.getMessage());
        }

    }


    @Produces
    public CacheManager produceCacheManager() {
        return cacheManager;
    }

上述类包含在我的 Web 应用程序的公共/共享模块中。 这对生产有好处,但是我需要一个集成测试的替代方案,它是使用带有 wildspike 集成的 Cucumber 完成的。

通过配置beans.xml,不幸的是我无法禁用上面的bean,我尝试以这种方式配置beans.xml:

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
    http://xmlns.jcp.org/xml/ns/javaee
    http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all">

    <scan>
        <exclude name="it.myapp.ecommerce.commons.resource.ServiceProducer"></exclude>
    </scan>
    

但是没有任何改变。是因为该类属于依赖项吗?

【问题讨论】:

  • 如果我没记错的话,&lt;exclude&gt; 过滤器必须在定义类的 bean 存档的 beans.xml 中工作。但是,alternatives+@Priority 可能适合您的情况。
  • 你能发一些sn-ps吗?我仍然不清楚如何使用资源提供者 bean 的 @alternative 注释,就像我发布的那样
  • 为了清楚起见,我已经有了生成记录器和实体管理器的替代类,但问题是我不能只使用它。启动黄瓜时,由于服务生产者类,我有模棱两可的注入
  • 您是否将生产者 method 注释为替代方法?
  • @NikosParaskevopoulos 是的,我做到了,然后我用替代配置 beans.xml,但我没有任何改进,即使排除公共模块的 resorces/test/META-INF/beans.xml 也不起作用

标签: java cdi weld jboss-weld java-ee-8


【解决方案1】:

你基本上有两种选择。

首先,这是通常推荐的选项,它是您声明的辅助 bean 上的 @Alternative 加上 @Priority 组合,并且仅在测试环境中添加。这样,它将被用于测试,但不会被用于生产。请注意,您必须只在测试环境中添加替代品,否则它会一直被拾取。例如,您可以直接在测试项目(或其源)下声明此 bean,以便主(生产)JAR 不包含它。 此外,您无需更改 beans.xml 即可实现上述目的。 Alternatives can be enabled either via @Priority or via beans.xml;前者是全局的,后者是 per-bean-archive。

第二个选项是 CDI 扩展,它将观察 ProcessAnnotatedType&lt;ServiceProducer&gt; 事件并将 veto() 正确的类。这意味着给定的类不会被选为 bean。这可以根据某些参数或您手头的其他任何参数有条件地完成。 鉴于您执行上述操作,您需要以某种方式添加ServiceProducer 的新测试实现。您可以再次通过在测试源中声明它来做到这一点(此处无需替代),但您也可以使用相同的扩展名通过BeanConfigurator SPI 在AfterBeanDiscovery 中注册合成bean。

虽然 CDI 扩展非常强大,但我建议您使用第一个选项,一旦您了解了一些替代方案及其启用的工作原理,它会更简单、更容易理解。

【讨论】:

  • 正如@Nikos 已经说过的那样,替代+优先是要走的路。不需要对 beans.xml 进行修改
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-07
  • 2019-03-21
  • 1970-01-01
  • 2012-11-13
  • 1970-01-01
相关资源
最近更新 更多