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

我有一个EJB类,我需要在其中注入两个bean – 一个应该由EJB容器注入,另一个应该是
Spring容器.

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

    @Inject
    private EJBClass a;

    @Autowired
    private SpringComponent b;

}

在这里,Spring拦截器试图拦截bean’a’的注入并且它失败了.我希望EJB容器注入bean’a’和Spring容器来注入bean’b’.

请告诉我一个出路.

最佳答案 通过自定义SpringBeanAutowiringInterceptor类,可以从自动布线中排除使用@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钩子来定制bean post处理器,以便仅包括我们需要自动连接的那些注释.

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

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

@Inject
private EJBClass a;

@Autowired
private SpringComponent b;

}

如果您遇到任何问题,请在评论中告知.也可以根据需要优化代码,并为任何编译/格式问题辩解.

点赞