如何从Spring上下文获取已被@Autowired注入的Bean?
问题:如何从Spring上下文获取已被@Autowired注入的Bean?
我正在深入理解各类Spring Bean上下文,搭建了一个小型应用,支持两种Bean创建方式:
- 通过XML配置文件注入
- 通过
@Autowired注解结合application.properties注入
从ClassPathXmlApplicationContext获取Bean正常,但手动创建上下文获取的Bean无法加载属性。
相关代码
application.properties
com.example.demo.Demo.beanName=BEAN_PROPERTIES
Bean定义
public interface IDemo { String getBeanName(); void setBeanName(String beanName); } @Component @Qualifier("demoAnnotation") public class Demo implements IDemo { private static final Logger log = LoggerFactory.getLogger(Demo.class); @Value("${com.example.demo.Demo.beanName:BEAN_NAME_DEFAULT}") private String beanName; @Override public String getBeanName() { return beanName; } @Override public void setBeanName(String beanName) { this.beanName = beanName; } }
应用启动类
@SpringBootApplication public class DemoApplication { private static final Logger log = LoggerFactory.getLogger(DemoApplication.class); // 自动注入的Bean,打印beanName返回'BEAN_PROPERTIES' @Autowired private IDemo demoAnnotation; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Bean CommandLineRunner run() { return args -> { // 手动创建的上下文获取的Bean,getBeanName()返回'BEAN_NAME_DEFAULT' ApplicationContext ctx = new AnnotationConfigApplicationContext(DemoApplication.class); // demoAnnotation = (IDemo) ctx.getBean(Demo.class); // 打印自动注入的Bean返回`BEAN_PROPERTIES` log.info(demoAnnotation.getBeanName()); }; } }
Gradle构建文件
plugins { id 'java' id 'org.springframework.boot' version '2.7.5' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }
更新内容:config.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="demoXML" class="com.example.demo.Demo"> <property name="beanName"><value>BEAN_XML</value></property> </bean> </beans>
解决方法
问题根源
你在CommandLineRunner里手动创建了AnnotationConfigApplicationContext实例,这个新上下文和Spring Boot启动的主应用上下文完全独立。新上下文没有加载application.properties配置,所以@Value注解只能取到默认值BEAN_NAME_DEFAULT;而自动注入的demoAnnotation来自主上下文,自然能读取到配置文件中的值。
正确获取方式
直接注入主上下文
不要手动创建新上下文,让Spring把主上下文注入到CommandLineRunner中,直接从主上下文获取Bean:@Bean CommandLineRunner run(ApplicationContext ctx) { return args -> { // 从主上下文获取Bean,能正确读取配置 IDemo demoFromCtx = ctx.getBean(IDemo.class); log.info(demoFromCtx.getBeanName()); // 输出BEAN_PROPERTIES }; }同时加载XML配置(若需要)
如果要让主上下文包含XML中的Bean,在启动类上添加@ImportResource注解引入XML配置:@SpringBootApplication @ImportResource("classpath:config.xml") public class DemoApplication { // ... 原有代码 }之后可以通过
ctx.getBean("demoXML")获取XML定义的Bean,其beanName值为BEAN_XML。
内容的提问来源于stack exchange,提问作者TMOTTM
相关产品推荐
相关产品推荐

