Spring框架中的上下文,如何理解上下文,什么是应用上下文

如何理解上下文

上下文是一个抽象的概念,通常指的是某个特定时刻或某个特定环境下的状态和条件。上下文可以包含各种信息(如变量、数据、状态、环境设置等),这些信息共同决定了程序或系统在当前时刻的行为。

1、在 Web 开发中,上下文通常包含了请求、会话、应用配置等信息,这些信息共同决定了程序的行为。

2、在 Spring 框架中,上下文的概念被进一步细化:

  • 请求上下文(Request Context):指处理单个 HTTP 请求时的环境。它包含了请求的所有信息,如请求头、请求参数、会话信息等。
  • 应用上下文(Application Context):指整个 Web 应用程序的环境。它包含了应用程序的所有配置信息、Bean定义、依赖注入等。
  • 线程上下文(Thread Context):指当前线程的环境。在多线程环境中,每个线程都有自己的上下文,包括线程局部变量、线程状态等。

Spring 的应用上下文

先看一段代码:

@Component
public final class SpringUtil implements BeanFactoryPostProcessor, ApplicationContextAware {
    
    private static ConfigurableListableBeanFactory beanFactory;

    private static ApplicationContext applicationContext;

    // 获取 并 赋值保存 配置列表工厂 的实例
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
        beanFactory = factory;
    }

    // 获取 并 赋值保存 应用上下文 的实例
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringUtil.applicationContext = context;
    }
}

这段代码主要用于在 spring 应用上下文启动时,获取并保存 应用上下文、配置列表工厂 的实例。

1、BeanFactoryPostProcessor 接口:实现该接口,需要重写 postProcessBeanFactory 方法。该接口用于在 Spring 容器实例化任何 bean 之前,对 ConfigurableListBeanFactory 进行修改。ConfigurableListBeanFactory 是 spring 中用于 访问和操作 bean 定义、bean实例 的接口。

怎么修改?----> 就是在重写的 postProcessBeanFactory 方法里:

@Component
public class Test implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        
        //1、获取并修改名为 myBean 的 bean 的定义:
        
        // 获取定义
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("myBean");
        // 修改定义
        beanDefinition.getPropertyValues().add("property", "newValue");
        
        //===========================================================
        
        //2、添加或删除bean:
        
        // 添加bean:其中MyBean就是myBean对象的类
        BeanDefinition beanDefinition = new RootBeanDefinition(MyBean.class);
        beanFactory.registerBeanDefinition("newBean", beanDefinition);
        
        //删除bean
        beanFactory.removeBeanDefinition("oldBean");
        
        //===========================================================
        
        //3、自定义bean的初始化逻辑:
        
        // 先获取bean的定义
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("myBean");
        
        // 修改bean的定义,添加初始化方法:这样,当Spring容器实例化 myBean 时,就会调用customInit 方法进行初始化(确保 MyBean 中有这个方法)
        beanDefinition.setInitMethodName("customInit");
        
    }
}

使用场景:

  1. 修改bean的定义:在Spring容器实例化bean之前,可以修改bean的定义,例如修改bean的属性值、添加或删除bean的依赖等。

  2. 添加或删除bean:在Spring容器实例化bean之前,可以添加或删除bean,例如根据某些条件动态添加或删除bean。

  3. 自定义bean的初始化逻辑:在Spring容器实例化bean之前,可以自定义bean的初始化逻辑,例如在bean的初始化方法之前执行一些额外的操作。


2、ApplicationContextAware 接口:实现该接口,需要重写 setApplicationContext 方法。该接口用于将 Spring 容器中的 ApplicationContext 实例注入到实现了该接口的类中。ApplicationContext 是 Spring 中用于 访问应用上下文和bean 的接口。

怎么注入?----> 就是在重写的 setApplicationContext 方法里,这个方法会在 Spring 容器初始化过程中被调用,并将 ApplicationContext 的实例注入到实现了该接口的类中。

使用场景:

  1. 获取bean实例:在Spring容器初始化过程中,可以通过ApplicationContext获取 bean 的实例。

  2. 获取应用上下文信息:可以通过ApplicationContext获取应用上下文的信息,例如获取应用上下文的ID、获取应用上下文的父上下文等。

  3. 发布事件:可以通过ApplicationContext发布事件,例如在某个操作完成后发布一个事件,其他实现了ApplicationListener接口的类可以监听这个事件并进行相应的处理。

@Component
public class Test implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //1、获取bean实例
        MyBean myBean = applicationContext.getBean(MyBean.class);
        // 使用bean实例
        myBean.doSomething();
        
        //2、获取应用上下文信息
        String contextId = applicationContext.getId();
        ApplicationContext parentContext = applicationContext.getParent();
        
        // 使用应用上下文信息
        System.out.println("Context ID: " + contextId);
        System.out.println("Parent Context: " + parentContext);
        
        //3、发布事件:这样,当 Spring 容器初始化 Test 时,就会将 ApplicationContext 实例注入到 Test 中,并调用 setApplicationContext 方法。同时,其他实现了ApplicationListener 接口的类可以监听这个事件并进行相应的处理。
        applicationContext.publishEvent(new MyEvent("Hello, World!"));
    }
}

上面 3 个场景:当 Spring 容器初始化 Test时,就会将 ApplicationContext 实例注入到Test中,并调用 setApplicationContext 方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小学鸡!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值