Spring组件扫描可识别标注@ApplicationScoped的CDI Bean吗?
问题解答
能否让Spring识别@ApplicationScoped标注的CDI Bean
可以实现,最直接的方案是自定义组件扫描过滤器,具体操作如下:
- 第一步:在你的Spring配置类上调整
@ComponentScan配置,增加包含过滤器,将标注了@ApplicationScoped的类纳入Spring组件扫描范围
示例配置代码:
注意:如果你的项目用的是旧版Java EE的CDI注解,包名是import jakarta.enterprise.context.ApplicationScoped; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.core.type.filter.AnnotationTypeFilter; @Configuration @ComponentScan(includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = ApplicationScoped.class)) public class AppConfig { }javax.enterprise.context.ApplicationScoped,替换成对应包名即可。 - 第二步:作用域映射匹配
CDI的@ApplicationScoped语义和Spring默认的Singleton作用域完全一致,被上述过滤器扫描进来的Bean默认会使用Spring的Singleton作用域,不需要额外配置。如果你需要兼容@RequestScoped、@SessionScoped这类其他CDI作用域,可以额外配置CustomScopeConfigurer做注解到Spring作用域的映射。
为什么Spring默认支持@Inject但不支持@ApplicationScoped
@Inject是JSR-330(Java依赖注入规范)定义的核心注解,属于跨框架的通用依赖注入标记,Spring从3.0版本开始就原生支持JSR-330的核心注解,只要引入了对应规范依赖就可以直接使用。
而@ApplicationScoped属于CDI(JSR-299/JSR-346)规范的注解,CDI本身是一套完整的企业级容器规范,包含了作用域管理、拦截器、装饰器、事件总线等大量Spring已经有独立实现的功能,Spring没有默认适配CDI的全套注解,主要是为了避免两套容器模型的特性冲突,减少不必要的兼容复杂度。
使用注意事项
如果你要集成的CDI Bean仅使用了基础的依赖注入能力,没有用到CDI拦截器、装饰器、事件、会话/请求作用域等进阶特性,上述方案可以完全正常运行,不需要额外改造。如果用到了CDI进阶特性,要么需要额外引入CDI运行时与Spring的桥接组件,要么建议将对应特性迁移为Spring原生实现。
内容的提问来源于stack exchange,提问作者pesche666
相关产品推荐
相关产品推荐

