Spring Boot注入Bean后如何正确获取并使用对应实例?
问题分析
你当前的实现存在两个核心问题:
- 配置类存在循环依赖:你在
PizzaConfiguration的构造器里注入Pizza实例,但这个Pizza实例本身又是当前配置类要创建的Bean,属于完全冗余的代码,直接删除构造器和对应的成员变量即可,修正后的配置类代码如下:
@Configuration public class PizzaConfiguration { @Bean public Pizza getPizza() { Pizza pizza = new Pizza(); pizza.hasCheese(true); pizza.addTopping("pepperoni"); pizza.addTopping("onions"); pizza.addTopping("sausage"); return pizza; } }
- 手动
new PizzaConfiguration的方式完全脱离了Spring容器的管理:Spring的Bean全部由Spring IOC容器统一创建、管理,你自己手动new出来的配置类实例,不会触发Spring的注解解析逻辑,自然拿不到容器里初始化好的pizza Bean。
正确访问Pizza Bean的三种常用方式
- 方式1:在Spring管理的类中直接注入
只要是被Spring管理的类(比如标注了@Controller、@Service、@Component、@RestController的类,以及其他@Configuration配置类),都可以通过构造器注入、@Autowired注入的方式直接拿到pizza Bean,示例:
// 示例:在业务Service中注入 @Service public class PizzaService { private final Pizza pizza; // Spring 4.3+之后,如果类只有一个构造器,@Autowired可以省略 public PizzaService(Pizza pizza) { this.pizza = pizza; } public void testPizza() { System.out.println(pizza.hasCheese()); // 返回true System.out.println(pizza.getToppings()); // 返回[pepperoni, onions, sausage] } }
- 方式2:从ApplicationContext中主动获取
如果你要在非Spring管理的普通类里拿这个Bean,可以先把ApplicationContext封装成工具类方便调用:
@Component public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtil.applicationContext = applicationContext; } public static <T> T getBean(Class<T> clazz) { return applicationContext.getBean(clazz); } }
之后在任何地方调用即可:
Pizza pizza = SpringContextUtil.getBean(Pizza.class);
- 方式3:启动时从SpringApplication返回的上下文获取
如果是在main方法里测试,直接拿SpringApplication.run返回的上下文获取即可:
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(DemoApplication.class, args); Pizza pizza = context.getBean(Pizza.class); // 直接使用pizza即可 } }
内容的提问来源于stack exchange,提问作者corgi77
相关产品推荐
相关产品推荐

