springboot开发的常用组件总结-组织组件

ApplicationContextAware

ApplicationContextAware 是 Spring 框架中的一个接口,它允许一个类访问 Spring
应用上下文(ApplicationContext),从而可以查询其中的 Bean,获取资源等。这个接口通常用于那些需要在其生命周期内访问
Spring 容器上下文的
Bean。实现这个接口的类需要实现一个方法:setApplicationContext(ApplicationContext
applicationContext),Spring 容器会在创建该 Bean 的实例后,自动调用此方法并传入当前的
ApplicationContext 实例。

使用场景

当你的 Bean 需要访问 Spring 容器中的其他 Bean,但又不想通过构造函数或 setter 方法注入时。

当你的 Bean 需要访问 Spring 容器提供的资源,如文件、环境变量等。

实现步骤

实现 ApplicationContextAware 接口。

实现 setApplicationContext 方法,保存传入的 ApplicationContext 实例。

在你的类中,通过保存的 ApplicationContext 实例来访问 Spring 容器中的 Bean 或资源。

示例
下面是一个使用 ApplicationContextAware 接口的示例,在实际应用中经常在其中使用反射方式获取一个接口的所有实现了的枚举。

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class MyBean implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    // 示例方法:通过 ApplicationContext 获取另一个 Bean
    public void doSomething() {
        // 假设我们有一个名为 "anotherBean" 的 Bean
        AnotherBean anotherBean = applicationContext.getBean(AnotherBean.class);
        // 使用 anotherBean 做一些事情
        anotherBean.doAnotherThing();
    }

    // AnotherBean 的定义
    public static class AnotherBean {
        public void doAnotherThing() {
            System.out.println("Doing another thing...");
        }
    }
}

在上面的示例中,MyBean 实现了 ApplicationContextAware 接口,并在 setApplicationContext
方法中保存了传入的 ApplicationContext 实例。然后,在 doSomething 方法中,通过保存的
ApplicationContext 实例来获取了另一个名为 AnotherBean 的 Bean,并对其进行了操作。

注意事项

虽然 ApplicationContextAware 提供了一种访问 Spring 容器的灵活方式,但过度使用它可能会导致代码与
Spring 框架的紧密耦合,降低代码的可测试性和可维护性。因此,建议仅在必要时使用它。

如果你只是需要注入少量的 Bean,建议使用 Spring 的依赖注入(DI)功能,如通过构造函数、setter 方法或字段注入。

在单元测试中,如果你需要模拟 ApplicationContext,可能需要使用一些额外的框架或工具,如 Mockito,来模拟 ApplicationContext 的行为。

BeanDefinitionRegistryPostProcessor

BeanDefinitionRegistryPostProcessor 是 Spring框架中用于在应用程序上下文(ApplicationContext)启动时修改 Bean 定义的接口。它扩展了
BeanFactoryPostProcessor 接口,并提供了对 Bean 定义注册表的直接访问,这允许在常规
BeanFactoryPostProcessor 处理之后添加、修改或删除 Bean 定义。

详解

BeanDefinitionRegistryPostProcessor 接口定义了一个方法
postProcessBeanDefinitionRegistry(BeanDefinitionRegistry
registry),该方法在所有的 Bean 定义被加载但还没有被实例化之前被调用。这允许你在 BeanFactory
加载过程中动态地添加、修改或删除 Bean 定义。

使用场景

动态地注册 Bean 定义,这些定义可能基于运行时条件或外部配置。

修改或删除已存在的 Bean 定义。

自定义 Bean 的生命周期或属性,这些在常规的 BeanFactoryPostProcessor 中可能无法直接实现。

Demo

下面是一个简单的 BeanDefinitionRegistryPostProcessor 实现示例,该示例在应用程序启动时动态地向 Spring 容器中注册一个新的 Bean 定义。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // 创建一个新的 Bean 定义
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(MyDynamicBean.class);
        
        // 设置 Bean 的属性(如果需要的话)
        // beanDefinitionBuilder.addPropertyValue("someProperty", "someValue");

        // 注册 Bean 定义
        BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        String beanName = "myDynamicBean";
        registry.registerBeanDefinition(beanName, beanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 这个方法在这个示例中不会被使用,因为它是 BeanDefinitionRegistryPostProcessor 的一部分
        // 但如果你需要访问 BeanFactory(而不是 BeanDefinitionRegistry),你可以在这里做
    }

    // 假设我们有一个简单的类来作为动态注册的 Bean
    public static class MyDynamicBean {
        // 类实现...
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一个双鱼座的测开

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

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

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

打赏作者

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

抵扣说明:

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

余额充值