当前位置: 首页 > article >正文

spring ApplicationContextAware的使用和执行时机

实际项目开发中,会写类似如下的工具类,方便做脚本执行或者一些判断,提供一些api方法等(可阅读:https://blog.csdn.net/qq_26437925/article/details/114213391 ,ApplicationContextAware就大派用场了),如下

@Component
public class SpringApplicationUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public 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拿到

@Test
	public 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;

    @Autowired
    private Y y;


    public X() {
        System.out.println("X()");
    }

    public void sy(){
        System.out.println("y:" + y);
    }

    @Override
    public void setBeanName(String name) {
        this.xName = name;
    }

    public void sayMyName(){
        System.out.println("xName:" + xName);
    }


在这里插入图片描述


http://www.kler.cn/a/502651.html

相关文章:

  • linux自动分区后devmappercentos-home删除后合并到其它分区上
  • 利用AI大模型和Mermaid生成流程图
  • 不同音频振幅dBFS计算方法
  • linux的大内核锁与顺序锁
  • Pandas常用数据类型
  • 稀疏编码 (Sparse Coding) 算法详解与PyTorch实现
  • [Qt]控件的核心属性
  • JavaEE——多线程代码案例2:阻塞队列
  • 从 SQL 语句到数据库操作
  • 51单片机——DS18B20温度传感器
  • ue5使用蓝图接口记录
  • 【Docker系列】容器内目录显示异常的解决之道
  • 【JVM-3】深入理解JVM堆内存:结构、管理与优化
  • STM32之LWIP网络通讯设计-上(十四)
  • 如何稳定使用 O1 / O1 Pro,让“降智”现象不再困扰?
  • Swagger生成Api文档的增强解决方案--knife4j
  • http和https有哪些不同
  • 【Ubuntu与Linux操作系统:一、Ubuntu安装与基本使用】
  • 45. 跳跃游戏2
  • 使用 Docker 部署 Java 项目(通俗易懂)
  • Java的Stream流和Option类
  • 深入解析 Python 中的函数参数类型详解
  • ​Vue虚拟DOM:如何提高前端开发效率
  • 44_Lua迭代器
  • 【IPy模块01】Python运维模块之IP 地址、网段的基本处理
  • Qt中.pro文件中可以填加的宏和其他的信息