1

Spring之后置处理器 - blue星空

 1 year ago
source link: https://www.cnblogs.com/BlueStarWei/p/16987442.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Spring之后置处理器 - blue星空 - 博客园

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

ContractedBlock.gifExpandedBlockStart.gif

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进行修改

ContractedBlock.gifExpandedBlockStart.gif

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;
    }
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK