Spring之后置处理器

时间:2022-12-16 16:04:18
 
Spring的后置处理器是Spring对外开发的重要扩展点,允许我们接入Bean的实例化流程中,以达到动态注册BeanDefinition动态修改BeanDefinition动态修改Bean的作用。
 
BeanFactoryPostProcessor
 
BeanFactory的后置处理器,在BeandefinitionMap填充完毕之后,Bean实例化之前执行。
BeanFactoryPostProcessor是一个接口规范,用于对BeanDefinition进行操作(注册、修改、删除)。
package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
BeanFactoryPostProcessor

 

应用

  • 方式一:自定义BeanFactoryPostProcessor接口实现类:实现BeanFactoryPostProcessor接口,并将实现类注册到Spring中,Spring就可以自动调用postProcessBeanFactory方法.
package com.blueStarWei.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 注册
        BeanDefinition definition = new RootBeanDefinition();
        definition.setBeanClassName("com.blueStarWei.ObjectBeanFactory");
        //必须强制转换为DefaultListableBeanFactory才能注册\删除
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) beanFactory;
        defaultListableBeanFactory.registerBeanDefinition("myBeanFactory",definition);

        //删除
        defaultListableBeanFactory.removeBeanDefinition("user");

        //修改
        BeanDefinition person = beanFactory.getBeanDefinition("person");
        person.setScope(BeanDefinition.SCOPE_PROTOTYPE);
    }
}
  • 方式二:自定义BeanDefinitionRegistryPostProcessor接口实现类:BeanDefinitionRegistryPostProcessor接口是BeanFactoryPostProcessor接口的子接口,主要用于注册BeanDefinition。【先调用postProcessBeanDefinitionRegistry(),再调用postProcessBeanFactory()】
package com.blueStarWei.processor;

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.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println(">>>>>>>1. postProcessBeanDefinitionRegistry");
        BeanDefinition definition = new RootBeanDefinition();
        definition.setBeanClassName("com.blueStarWei.ObjectBeanFactory");
        registry.registerBeanDefinition("myBeanFactory",definition);
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println(">>>>>>>>>>2. postProcessBeanFactory");
    }
}
注意:当方式一与方式二同时使用时,调用顺序为:
  • BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()
  • BeanDefinitionRegistryPostProcessor.postProcessBeanFactory()
  • BeanFactoryPostProcessor.postProcessBeanFactory()

 

BeanPostProcessor

Bean的后置处理器,一般在Bean的初始化前后执行。Bean实例化之后,填充到单例池singletonObjects之前执行,会进行Bean的初始化。
BeanPostProcessor是一个接口规范,用于对Bean进行修改
package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;

public interface BeanPostProcessor {

   /**
    * 在Bean的初始化之前执行
    */
   Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

   /**
    * 在Bean的初始化之后执行
    */
   Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}
BeanPostProcessor

 

应用

  • 使用动态代理进行Bean的功能增强
package com.blueStarWei.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.Proxy;

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    /**
     * 打印方法调用时间日志 
     * 注意:使用jdk自带的Proxy只能对有接口的类进行动态代理,直接代理POJO会报类型ClassCastException
     *
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Object beanProxy = Proxy.newProxyInstance(
                bean.getClass().getClassLoader(),
                bean.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    long startTime = System.currentTimeMillis();
                    Object result = method.invoke(bean, args);
                    long endTime = System.currentTimeMillis();
                    System.out.println(beanName + "." + method.getName() + "执行时间:" + (endTime - startTime) + "ms.");
                    return result;
                }
        );
        return beanProxy;
    }
}