简体   繁体   English

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

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

I have the following @ApplicationScoped bean:我有以下@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;
    }

The above class is contained in a common / shared module of my web applications.上述 class 包含在我的 web 应用程序的公共/共享模块中。 This is good for production, however I need an alternative for integration test, which are done with Cucumber with wildspike integration.这对生产有好处,但是我需要一个集成测试的替代方案,它是使用 Cucumber 和 wildspike 集成完成的。

By configuring beans.xml, unfortunately I cannot disable the bean above, I tried with configuring beans.xml in this way:通过配置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>
    

however nothing changes.但是没有任何改变。 Is it due because the class belongs from a dependency?是因为 class 属于依赖项吗?

You basically have two options.你基本上有两个选择。

Firstly, and this is the usual go-to recommended option, it's the @Alternative plus @Priority combination on the secondary bean that you declare and only add in test environment.首先,这是通常推荐的选项,它是您声明的辅助 bean 上的@Alternative加上@Priority组合,并且仅在测试环境中添加。 That way, it will be picked up for testing but not in production.这样,它将被用于测试,但不会被用于生产。 Note that it is imperative that you only add the alternative in the test environment else it would be picked up at all times.请注意,您必须只在测试环境中添加替代品,否则它会一直被拾取。 You can, for instance, declare this bean directly under test project (or its sources) so that the main (production) JAR doesn't contain it.例如,您可以直接在测试项目(或其源)下声明此 bean,以便主(生产)JAR 不包含它。 Furthermore, you don't need to alter beans.xml to achieve the above.此外,您无需更改beans.xml即可实现上述目的。 Alternatives can be enabled either via @Priority or via beans.xml ; 可以通过@Prioritybeans.xml启用替代方案 the former is global, the latter is per-bean-archive.前者是全局的,后者是 per-bean-archive。

Second option is a CDI extension that will observe ProcessAnnotatedType<ServiceProducer> event and will veto() the proper class.第二个选项是 CDI 扩展,它将观察ProcessAnnotatedType<ServiceProducer>事件并veto()正确的 class。 That means the given class won't be picked up as bean.这意味着给定的 class 不会作为 bean 被拾取。 This can be done conditionally based on some parameter or whatever else you have at hand.这可以根据某些参数或您手头的任何其他参数有条件地完成。 Given you do the above, you then need to somehow add the new test implementation of ServiceProducer .鉴于您执行上述操作,您需要以某种方式添加ServiceProducer的新测试实现。 You can again do that by declaring it in test sources (no need for alternative here) but you can also use the very same extension to register a synthetic bean in AfterBeanDiscovery via BeanConfigurator SPI .您可以再次通过在测试源中声明它来做到这一点(此处无需替代),但您也可以使用相同的扩展通过BeanConfigurator SPIAfterBeanDiscovery中注册合成 bean。

While CDI extension are pretty powerful, I'd recommend going with the first option that's way simpler and more understandable once you read up a bit on how alternatives and their enablement works.虽然 CDI 扩展非常强大,但我建议您使用第一个选项,一旦您阅读了一些关于替代方案及其启用的工作原理,它会更简单、更容易理解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM