Java Spring后处理器

Java Spring后处理器

在Spring框架中,交给Spring管理的类信息都会被Spring底层自动加载被封装成对应的BeanDefinition对象存储在beanDefinitionMap的Map集合中去,那么除了直接将类信息配置的方式外,还有别的方式可以对想要交给Spring管理的类进行针对性处理封装,这里就可以使用到Spring的后处理器。

后处理器:是Spring对外开放的重要扩展点,允许我们介入到Bean的整个实例化流程中来,以达到动态注册BeanDefinition,动态修改BeanDefinition,以及动态修改Bean的作用


Spring的后处理器分为两类:BeanFactoryPostProcessorBeanPostProcessor

  • BeanFactoryPostProcessor:Bean工厂后处理器,在BeanDefinitionMap填充完毕,Bean实例化之前执行
  • BeanPostProcessor:Bean后处理器,一般在Bean实例化之后,填充到单例池singletonObjects之前执行

Bean实例化链接:Bean的实例化

在这里插入图片描述


BeanFactoryPostProcessor样例:

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("beanDefinitionMap填充完毕后,Spring容器回调此方法");

        //功能一:修改BeanDefinition的信息
        //根据BeanName获取封装的BeanDefinition对象
        BeanDefinition myClass= configurableListableBeanFactory.getBeanDefinition("myClass");
        myClass.setBeanClassName("com.test.MyClassChange");

        //功能二:注册BeanDefinition到beandDefinitionMap中
        //设置BeanDefinition的Bean信息
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClassName("com.test.MyClassNew");
        //进行BeanDefinition注册
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
        defaultListableBeanFactory.registerBeanDefinition("myClassNew",rootBeanDefinition);

    }
}

FactoryBeanProcessor工厂后处理,可以 修改 beanBeanDefintionMap中注册的BeanBeanDefintion内容或者 新注册 BeanBeanDefintion到beanBeanDefintionMap中去,注册功能可以理解注解的实现,工厂后处理器去遍历带上注解的类,让后将其进行注册

BeanFactoryPostProcessor类似注解实现样例:

public class MyComponentBeanFactoryPostPocessor implements BeanDefinitionRegistryPostProcessor {
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        // 通过扫描工具去扫描指定包及其子包下的所有类,收集使用@MyComponent的注解的类
        Map<String, Class> myComponentAnnotationMap = BaseClassScanUtils.scanMyComponentAnnotation("com.test");
        // 遍历Map,组装BeanDefinition对象
        Iterator<String> iterator = myComponentAnnotationMap.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String className = myComponentAnnotationMap.get(key).getName();
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
            //获取待注册的类名
            rootBeanDefinition.setBeanClassName(className);
            //进行BeanDefinition注册
            beanDefinitionRegistry.registerBeanDefinition(key, rootBeanDefinition);
            System.out.println("工厂后处理器注册了" + key + "对象");
        }
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

注册的时候可以用专用子接口BeanDefinitionRegistryPostProcessor去注册,此接口在BeanFactoryPostProcessor之前执行


BeanPostProcessor样例:

public class MyBeanPostProcessor implements BeanPostProcessor {

	//在init方法执行之前执行
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + ":postProcessBeforeInitialization");
            //判断Bean的实例类型
	        if(bean instanceof MyClass){
            MyClass myClass= (MyClass) bean;
            //MyClass中有个String属性attribute,在此处可以注入值
            myClass.setAttribute("setAttribute");
        }
        return null;
    }
    
	//在init方法执行之后执行
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + ":postProcessAfterInitialization");
        return null;
    }
}

BeanPostProcessor可以修改Bean的内容,先创建Bean的构造方法,再执行postProcessBeforeInitialization方法、执行Bean的其他方法(init初始化方法等)、最后执行postProcessAfterInitialization方法

Spring的AOP代理增强就是基于此后处理的原理进行实现,可以在Bean实例中进行切面的织入

AOP博客链接:AOP博客链接

代理博客链接:代理博客链接

BeanFactoryPostProcessor类似AOP实现样例:

public class myAopBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        // 使用动态代理,对目标Bean进行增强,返回proxy对象,进而存储到单例池singletonObjects中
        Object beanProxy = Proxy.newProxyInstance(
                bean.getClass().getClassLoader(),
                bean.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    //1、前置增强
                    System.out.println("方法:" + method.getName() + "-开始时间:" + new Date());
                    //2、执行目标方法
                    Object result = method.invoke(bean, args);
                    //3、后置增强
                    System.out.println("方法:" + method.getName() + "-结束时间:" + new Date());

                    return result;
                }
        );

        return beanProxy;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值