spring - 配置 Spring 以忽略使用 @Inject 注释的依赖项

标签 spring jakarta-ee dependency-injection ejb cdi

我有一个 EJB 类,需要在其中注入(inject)两个 bean - 一个应该由 EJB 容器注入(inject),另一个是 Spring 容器。

@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
@LocalBean
public class SomeClass {

    @Inject
    private EJBClass a;

    @Autowired
    private SpringComponent b;

}

这里,Spring 拦截器试图拦截 bean 'a' 的注入(inject),但失败了。我希望 EJB 容器注入(inject) bean 'a',Spring 容器注入(inject) bean 'b'。

请给我指明一条出路。

最佳答案

通过自定义SpringBeanAutowiringInterceptor类,可以从 Autowiring 中排除使用@Inject注释的依赖项。

要了解幕后发生的事情,请查看源代码 SpringBeanAutowiringInterceptor.java -

/**
 * Actually autowire the target bean after construction/passivation.
 * @param target the target bean to autowire
 */
protected void doAutowireBean(Object target) {
    AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
    configureBeanPostProcessor(bpp, target);
    bpp.setBeanFactory(getBeanFactory(target));
    bpp.processInjection(target);
}

doAutowireBean 的第一行,创建了一个AutowiredAnnotationBeanPostProcessor 的新实例。这里配置了要扫描自动连接依赖项的注释集。

/**
 * Create a new AutowiredAnnotationBeanPostProcessor
 * for Spring's standard {@link Autowired} annotation.
 * <p>Also supports JSR-330's {@link javax.inject.Inject} annotation, if available.
 */
@SuppressWarnings("unchecked")
public AutowiredAnnotationBeanPostProcessor() {
    this.autowiredAnnotationTypes.add(Autowired.class);
    this.autowiredAnnotationTypes.add(Value.class);
    try {
        this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
                ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
        logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
    }
    catch (ClassNotFoundException ex) {
        // JSR-330 API not available - simply skip.
    }
}

由于默认情况下配置了 @Inject 注释,spring 会扫描标有 @Inject 的各个依赖项并尝试自动连接它们。

要排除 @Inject 带注释的依赖项,请在自定义类下方写入。

public class CustomSpringBeanAutowiringInterceptor extends SpringBeanAutowiringInterceptor {

    /**
     * Template method for configuring the
     * {@link AutowiredAnnotationBeanPostProcessor} used for autowiring.
     * @param processor the AutowiredAnnotationBeanPostProcessor to configure
     * @param target the target bean to autowire with this processor
     */
    protected void configureBeanPostProcessor(AutowiredAnnotationBeanPostProcessor processor, Object target) {
        Set<Class> annotationsToScan = new HashSet<Class>();
        annotationsToScan.add(Autowired.class);
        annotationsToScan.add(Value.class);
        processor.setAutowiredAnnotationTypes(annotationsToScan);

    }
}

这里使用configureBeanPostProcessor钩子(Hook)来自定义bean后处理器,以便仅包含我们需要自动连接的注释。

在代码中应用此自定义类作为拦截器后,可以实现所需的行为

@Stateless
@Interceptors(CustomSpringBeanAutowiringInterceptor.class)
@LocalBean
public class SomeClass {

@Inject
private EJBClass a;

@Autowired
private SpringComponent b;

}

如果您遇到任何问题,请在评论中告知。也可以随意优化代码,并原谅任何编译/格式问题。

关于spring - 配置 Spring 以忽略使用 @Inject 注释的依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37592743/

相关文章:

dependency-injection - 是否可以通过约定在.NET Core中注册依赖项?

dependency-injection - 温莎城堡注入(inject)构造对象的属性

java - 使用 Java 泛型为实体实现转换器

java - 无法从 Eclipse 运行 Tomcat 7

java - 避免双循环

jakarta-ee - java.lang.NoClassDefFoundError : javax/servlet/http/HttpServlet

c# - 为同一接口(interface)的多个实现设置属性

java - 在自定义 validator Spring Hibernate 中注入(inject) @PersistenceContext

spring - 如何创建 Redis 条件 Bean?

java - 使用 spring mvc 在 web 服务中公开 bean 时出现异常