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

Spring容器扩展点

Spring容器扩展点

  • BeanDefinitionRegistryPostProcessor
  • BeanFactoryPostProcessor
  • ImportSelector
  • ImportBeanDefinitionRegistor
  • BeanPostProcessor
    • InstantiationAwareBeanPostProcessor--postProcessBeforeInstantiation
    • SmartInstantiationAwareBeanPostProcessor--determineCandidateConstructors
    • MergedBeanDefinitionPostProcessor--postProcessMergedBeanDefinition
    • SmartInstantiationAwareBeanPostProcessor--getEarlyBeanReference
    • InstantiationAwareBeanPostProcessor--postProcessAfterInstantiation
    • InstantiationAwareBeanPostProcessor--postProcessProperties
    • BeanPostProcessor--postProcessBeforeInitialization
    • BeanPostProcessor--postProcessAfterInitialization
  • Aware--初始化阶段调用
  • 多种Bean初始化方法执行顺序
  • Bean创建完成之后
  • 多种Bean销毁方法执行顺序

BeanDefinitionRegistryPostProcessor

用来注册BeanDefinition,后期可生成bean。processor本身也会注册为Bean。

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        //可以使用builder来获取BeanDefinition, 也可以手动创建
//        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(OrderService.class);
//        BeanDefinition beanDefinition1 = builder.getBeanDefinition();

        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClass(OrderService.class);
        beanDefinition.getPropertyValues().add("orderId", 001);
        registry.registerBeanDefinition("orderService", beanDefinition);

    }

@Configuration
@ComponentScan
public class AppConfig {
}

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        OrderService orderService = (OrderService) applicationContext.getBean("orderService");
        System.out.println(orderService);

    }
}

BeanFactoryPostProcessor

可以注册/修改BeanDefinition,或者修改Bean工厂里面的Bean。processor本身也会注册为Bean。

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        OrderService orderService = (OrderService) configurableListableBeanFactory.getBean("orderService");
        orderService.setOrderId(2L);
    }
}

ImportSelector

配置@Import使用,导入需要生成Bean的类,最终生成的Bean名称与类名相同。selector本身不会成为Bean。

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"com.hoitung.fyz.SpringPostProcessor.OrderService"};
    }
}

@Configuration
//@ComponentScan
@Import(MyImportSelector.class)
public class AppConfig {
}

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        //OrderService orderService = (OrderService) applicationContext.getBean("orderService");
        OrderService orderService = applicationContext.getBean(OrderService.class);
        System.out.println(orderService);

    }
}

ImportBeanDefinitionRegistor

配合@Import使用,可以注册BeanDefinition,本身不会生成Bean。有个很重要的功能是可以获取@Import注解所在类的其他注解信息。MyBatis整合Spring使用了该方法。

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(OrderService.class);
        BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();

        beanDefinitionRegistry.registerBeanDefinition("orderServiceImport", beanDefinition);

        //AnnotationMetadata 可获取import注解所在类的其他注解信息
        System.out.println(annotationMetadata.getAnnotationAttributes(ComponentScan.class.getName()));
    }
}

@Configuration
@ComponentScan
@Import(MyImportBeanDefinitionRegistrar.class)
public class AppConfig {
}

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        //OrderService orderService = (OrderService) applicationContext.getBean("orderService");
        OrderService orderService = applicationContext.getBean(OrderService.class);
        System.out.println(orderService);

    }
}

BeanPostProcessor

InstantiationAwareBeanPostProcessor–postProcessBeforeInstantiation

在createBean中实例化前调用,如果改后置处理器返回了一个Bean,后续流程不会走。

@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        //此处返回实例对象,中断bean的生命周期
        if(beanName.equals("orderServiceImport")) {
            System.out.println(beanName+"实例化前返回对象,会中断bean的生命周期");
            return new OrderService();
        } else {
            //此处返回null,还会继续bean的生命周期
            return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
        }
    }
}

SmartInstantiationAwareBeanPostProcessor–determineCandidateConstructors

bean实例化时调用,返回实例化可使用的构造函数。

@Component
public class MySmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {

    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
        if(beanClass == OrderService.class) {
            try {
                return new Constructor[]{beanClass.getConstructor(Long.class)};
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            }
        }

        return SmartInstantiationAwareBeanPostProcessor.super.determineCandidateConstructors(beanClass, beanName);
    }
}

public class OrderService implements BeanNameAware {
    private Long orderId;
    private String beanName;

    public OrderService(Long orderId) {
        System.out.println("使用只有一个参数的构造器");
        this.orderId = orderId;
    }

    public OrderService(Long orderId, String beanName) {
        System.out.println("使用有两个参数的构造器");
        this.orderId = orderId;
        this.beanName = beanName;
    }

    public void setOrderId(Long orderId) {
        this.orderId = orderId;
    }

    @Override
    public void setBeanName(String s) {
        beanName = s;
    }

    @Override
    public String toString() {
        return "OrderService{" +
                "orderId=" + orderId +
                ", beanName='" + beanName + '\'' +
                '}';
    }
}

@Configuration
@ComponentScan
@Import(MyImportBeanDefinitionRegistrar.class)
public class AppConfig {

    @Bean
    public Long orderId() {
        return 10001L;
    }
}

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        //OrderService orderService = (OrderService) applicationContext.getBean("orderService");
        OrderService orderService = applicationContext.getBean(OrderService.class);
        System.out.println(orderService);

    }
}

运行结果:

使用只有一个参数的构造器
OrderService{orderId=10001, beanName='orderServiceImport'}

MergedBeanDefinitionPostProcessor–postProcessMergedBeanDefinition

实例化后,为属性注入做准备,预解析@Autowired @Value。可以使用该方法修改beanDefinition属性注入的值。

@Component
public class MyMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition rootBeanDefinition, Class<?> aClass, String s) {
        if(aClass == OrderService.class) {
            System.out.println(s+"实例化后给属性注入做准备,可以给BeanDefinition指定注入的值");
            rootBeanDefinition.getPropertyValues().add("orderId", 9000);
        }

    }
}

public class OrderService implements BeanNameAware {
    private Long orderId;
    private String beanName;

//    public OrderService(Long orderId) {
//        System.out.println("使用只有一个参数的构造器");
//        this.orderId = orderId;
//    }
//
//    public OrderService(Long orderId, String beanName) {
//        System.out.println("使用有两个参数的构造器");
//        this.orderId = orderId;
//        this.beanName = beanName;
//    }

    public void setOrderId(Long orderId) {
        this.orderId = orderId;
    }

    @Override
    public void setBeanName(String s) {
        beanName = s;
    }

    @Override
    public String toString() {
        return "OrderService{" +
                "orderId=" + orderId +
                ", beanName='" + beanName + '\'' +
                '}';
    }
}


public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        //OrderService orderService = (OrderService) applicationContext.getBean("orderService");
        OrderService orderService = applicationContext.getBean(OrderService.class);
        System.out.println(orderService);

    }
}

运行结果:

orderServiceImport实例化后给属性注入做准备,可以给BeanDefinition指定注入的值
OrderService{orderId=9000, beanName='orderServiceImport'}

SmartInstantiationAwareBeanPostProcessor–getEarlyBeanReference

主要用于处理循环依赖问题。getEarlyBeanReference方法允许在Bean完全初始化之前,提前返回一个Bean的早期引用,其他依赖该Bean的Bean可以使用这个早期引用,从而避免循环依赖导致的死锁问题。

InstantiationAwareBeanPostProcessor–postProcessAfterInstantiation

postProcessAfterInstantiation方法是Spring Bean生命周期中的一个重要扩展点,允许开发者在Bean实例化之后、属性填充之前执行自定义逻辑。返回true继续属性填充,返回false表示跳过属性填充。

@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

//    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//        //此处返回实例对象,中断bean的生命周期
//        if(beanName.equals("orderServiceImport")) {
//            System.out.println(beanName+"实例化前返回对象,会中断bean的生命周期");
//            return new OrderService(1001L);
//        } else {
//            //此处返回null,还会继续bean的生命周期
//            return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
//        }
//    }

    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if(bean instanceof OrderService) {
            System.out.println(beanName+"跳过属性注入");
            return false;
        }
        return true;
    }
}

运行结果:

orderServiceImport跳过属性注入
OrderService{orderId=null, beanName='orderServiceImport'}

InstantiationAwareBeanPostProcessor–postProcessProperties

属性填充阶段,开发者可以通过该方法对属性值进行修改或替换。

@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if(bean instanceof OrderService) {
            MutablePropertyValues mpv = pvs instanceof MutablePropertyValues ? (MutablePropertyValues) pvs : new MutablePropertyValues(pvs);
            mpv.add("userName", "test");
            return mpv;
        }
        return null;
    }
}

public class OrderService implements BeanNameAware {
    @Autowired
    private Long orderId;
    @Autowired
    private String userName;
    private String beanName;

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setOrderId(Long orderId) {
        this.orderId = orderId;
    }

    @Override
    public void setBeanName(String s) {
        beanName = s;
    }

    @Override
    public String toString() {
        return "OrderService{" +
                "orderId=" + orderId +
                ", userName='" + userName + '\'' +
                ", beanName='" + beanName + '\'' +
                '}';
    }
}

运行结果:

OrderService{orderId=10001, userName='test', beanName='orderServiceImport'}

BeanPostProcessor–postProcessBeforeInitialization

Bean的初始化方法执行之前,对Bean进行一些额外的处理

BeanPostProcessor–postProcessAfterInitialization

在Bean初始化方法执行之后调用,此时已经有完整的bean。

Aware–初始化阶段调用

ApplicationContextAware
BeanFactoryAware
BeanNameAware
EmbeddedValueResolverAware–spel表达式解析
EnvironmentAware
ApplicationEventPublisherAware–获取事件发布器,发布事件继承ApplicationEvent,实现ApplicationListener监听

public class OrderService implements BeanNameAware, ApplicationEventPublisherAware {
    @Autowired
    private Long orderId;
    @Autowired
    private String userName;
    private String beanName;
    private ApplicationEventPublisher applicationEventPublisher;

    public void placeOrder() {
        applicationEventPublisher.publishEvent(new OrderEvent(this, "orderEvent"));
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setOrderId(Long orderId) {
        this.orderId = orderId;
    }

    @Override
    public void setBeanName(String s) {
        beanName = s;
    }

    @Override
    public String toString() {
        return "OrderService{" +
                "orderId=" + orderId +
                ", userName='" + userName + '\'' +
                ", beanName='" + beanName + '\'' +
                '}';
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
}

public class OrderEvent extends ApplicationEvent {
    public OrderEvent(Object source, String msg) {
        super(source);
        System.out.println(msg);
    }
}

@Component
public class OrderEventListener implements ApplicationListener<OrderEvent> {
    @Override
    public void onApplicationEvent(OrderEvent orderEvent) {
        System.out.println("监听到事件:"+orderEvent.toString());
    }
}

MessageSourceAware–国际化
ResourceLoaderAware-资源加载器,加载类路径下的文件

@Component
public class ResourceUtil implements ResourceLoaderAware {

    private ResourceLoader resourceLoader;

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    public void showResourceData() throws IOException {
        Resource resource = resourceLoader.getResource("classpath:spring.yml");
        BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream()));
        while(true) {
            String s = br.readLine();
            if(StringUtils.isEmpty(s)) {
                break;
            }
            System.out.println(s);
        }


    }
}

resource下增加一个配置文件spring.xml:

order:
  userName: zls

运行结果:

order:
  userName: zls

多种Bean初始化方法执行顺序

@PostConstruct
实现接口InitializingBean的afterPropertiesSet方法
指定bean的init-method

Bean创建完成之后

SmartInitializingSingleton接口–所有Bean初始化完成之后调用
SmartLifecycle接口–spring容器加载完之后,可以做缓存预热,定时器启动关闭等
ContextRefreshedEvent–容器加载完成之后会发布这个事件,可以监听这个事件
ContextStoppedEvent
ContextClosedEvent

多种Bean销毁方法执行顺序

@PreDestroy
实现DisposableBean接口的destroy方法
指定bean的destroy-method


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

相关文章:

  • 新手小白学习docker第十弹-------Docker微服务实战
  • LLM 概述
  • 轨迹流动,实现语音转文字
  • tailwindcss学习01
  • 【图像加密解密】空间混沌序列的图像加密解密算法复现(含相关性检验)【Matlab完整源码 2期】
  • 夜莺监控发布 v8.beta5 版本,优化 UI,新增接口认证方式便于鉴权
  • 公牛充电桩协议对接单车汽车平台交互协议外发版
  • FFmpeg + Nginx + HLS流媒体播放方案
  • 深入理解TT无人机曲线飞行和挑战卡飞行+EP机甲全面运动
  • 【Windows软件 - HeidiSQL】导出数据库
  • Linux系统资源监控:全面掌握目录、文件、内存和硬盘使用情况
  • C++基础知识学习记录—string类
  • lwip和tcp/ip区别
  • 鸿蒙NEXT开发-沉浸式导航和键盘避让模式
  • Ubuntu 20 掉显卡驱动的解决办法
  • 利用 UniApp 实现带有渐变背景的盒子
  • mysql和minio
  • SpringCloud面试题----什么是Zuul微服务网关
  • 【网络基本知识--2】
  • Qt QListWidget 总结