实际项目开发中,会写类似如下的工具类,方便做脚本执行或者一些判断,提供一些api方法等(可阅读:https://blog.csdn.net/qq_26437925/article/details/114213391 ,ApplicationContextAware就大派用场了),如下
@Component
public class SpringApplicationUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringApplicationUtil.applicationContext = applicationContext;}public static Object getBean(String beanName){return applicationContext.getBean(beanName);}public static List<String> getAllBeanNames(){String[] arr = applicationContext.getBeanDefinitionNames();if(arr == null || arr.length == 0){return new ArrayList<>();}return Arrays.stream(arr).collect(Collectors.toList());}}
如下测试代码, 想拿到某个bean, 直接从这个util拿到
@Testpublic void test2() throws Exception {ApplicationContext ctx =new AnnotationConfigApplicationContext(LocalConfig.class, LocalConfig2.class);// 直接从工具类获取UserService userService = (UserService)SpringApplicationUtil.getBean("userService");Assert.assertNotNull(userService);userService.add(new User());((AnnotationConfigApplicationContext) ctx).close();}
本文来探究一下它是如何工作的。
直接debug可以看到执行链路,进行具体分析
可以发现在这个bean的初始化阶段,会执行所有的BeanPostProcessor扩展的postProcessBeforeInitialization方法,会发现执行到了ApplicationContextAwareProcessor
ApplicationContextAwareProcessor怎么来的?
org.springframework.context.support.AbstractApplicationContext的refresh方法中的prepareBeanFactory(beanFactory);
执行添加的,平台内置的一个beanPostProcessor
所以回到org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization 方法中,可以看到会执行Aware接口
private void invokeAwareInterfaces(Object bean) {if (bean instanceof Aware) {if (bean instanceof EnvironmentAware) {((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());}if (bean instanceof EmbeddedValueResolverAware) {((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);}if (bean instanceof ResourceLoaderAware) {((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);}if (bean instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);}if (bean instanceof MessageSourceAware) {((MessageSourceAware) bean).setMessageSource(this.applicationContext);}if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);}}
}
执行ApplicationContextAware的setApplicationContext方法完成设置, 如下
其实就是AnnotationConfigApplicationContext自身,即Spring容器管理者自身。
再比如BeanAware接口, 一个Bean想知道自己的beanName,那么自己实现下BeanNameAware
public class X implements BeanNameAware {private String xName;@Autowiredprivate Y y;public X() {System.out.println("X()");}public void sy(){System.out.println("y:" + y);}@Overridepublic void setBeanName(String name) {this.xName = name;}public void sayMyName(){System.out.println("xName:" + xName);}