WELD - 从扫描中排除应用程序范围的 bean / beans.xml

WELD - exclude application scoped bean from scanning / beans.xml

我有以下@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;
    }

以上 class 包含在我的网络应用程序的公共/共享模块中。 这对生产很有用,但是我需要一个集成测试的替代方案,这是用带有 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>
    

但是没有任何变化。是因为 class 属于依赖项吗?

你基本上有两个选择。

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

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

中注册合成 bean

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