能否将Spring Bean定义为Configuration类的本地私有Bean?
限制Spring Bean可见范围的实现方案
问题背景
给定如下Spring配置类:
@Configuration class SpringConfig { @Bean MyBean myBean() { return new MyBean(); } @Bean OtherBean otherBean(MyBean myBean) { return new OtherBean(myBean); } @Bean AnotherBean anotherBean(MyBean myBean) { return new AnotherBean(myBean); } }
希望myBean仅作为OtherBean和AnotherBean的依赖,不被其他Bean自动注入/装配,能否通过将其定义为SpringConfig类的本地私有Bean来实现该限制?
核心结论
不能通过将myBean()方法设为私有来实现该限制,反而会导致Spring上下文初始化失败。
原因说明
Spring处理@Configuration类时,会通过CGLIB生成代理类,代理类需要访问配置类中的@Bean方法来实现Bean的单例缓存、依赖注入等生命周期管理逻辑。如果将myBean()设为私有,代理类无法通过反射访问该方法,会直接抛出异常,导致容器启动失败。
正确实现方案
方案1:设置autowireCandidate = false
修改myBean的@Bean注解,将其标记为非自动注入候选对象。这样外部Bean无法通过@Autowired、@Resource等方式自动装配它,但当前配置类的其他@Bean方法仍可正常依赖注入或直接调用该方法获取实例:
@Configuration class SpringConfig { @Bean(autowireCandidate = false) MyBean myBean() { return new MyBean(); } @Bean OtherBean otherBean(MyBean myBean) { return new OtherBean(myBean); } @Bean AnotherBean anotherBean(MyBean myBean) { return new AnotherBean(myBean); } }
此方案下myBean依然受Spring管理(支持生命周期回调、AOP等),仅限制了自动注入的可见性。
方案2:直接内部实例化(不暴露为Spring Bean)
如果myBean不需要Spring的生命周期管理,可以不在配置类中单独定义@Bean,而是在创建OtherBean和AnotherBean时直接实例化:
@Configuration class SpringConfig { @Bean OtherBean otherBean() { return new OtherBean(new MyBean()); } @Bean AnotherBean anotherBean() { return new AnotherBean(new MyBean()); } }
注意:这种方式下每个依赖Bean会得到独立的MyBean实例,若需要单例,建议使用方案1。
内容的提问来源于stack exchange,提问作者Dónal
相关产品推荐
相关产品推荐

