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 扩展非常强大,但我建议您使用第一个选项,一旦您了解了替代方案及其支持的工作原理,它会更简单、更容易理解。
我有以下@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.
虽然 CDI 扩展非常强大,但我建议您使用第一个选项,一旦您了解了替代方案及其支持的工作原理,它会更简单、更容易理解。