😉😉 学习交流群:

✅✅1:这是孙哥suns给大家的福利!

✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料

🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取!

🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞

一:BeanPostProcessor分析

1:BeanPostProcessor对于Spring工厂作用

        这个事后置处理Bean,这个东西的全称叫做BeanPostProcessor,最主要的作用是对Spring创建的对象进行再加工,这个是Spring工厂中的一个非常有用的高级特性,在Spring底层很多高级的封装的时候都有这个技术的影子,讲了Aop底层的实现的时候,会发现这个技术的价值是非常高的,Spring的Aop底层实现很大的一部分是这个技术进行支撑。

        BeanPostProcessor是对Spring的bean工厂进行在加工,Spring工厂创建对象的过程是:Spring获取Spring的核心配置文件之后对spring的核心配置文件进行解析,获取到响应的bean标签会后,通过反射技术调用该类的构造方法,创建该类的实例,第二件事是spring对这个类中的成员变量按照配置进行注入,注入完成之后,调用这个类的初始化方法,对这个类进行一个初始化,这个初始化方法是我们自己定义的,经过这样的一个过程,这个对象就创建并初始化好了,现在就可以通过getBean通过id进行获取这个对象,而这个后置处理bean,是在工厂创建完成这个对象之后,对这个对象进行再次加工,这就是这门技术的意义,那么她是怎么实现对这个工厂创建出来的对象进行再次加工的呢?BeanPostProcessor是一个接口,我们需要把这个对象加工的内容写到接口实现类对应的方法中即可。

        在这个接口当中呢有两两个方法,第一个方法是postProcessBeforeInitialization,另外的方法叫after,,这样的接口,当Bean实现了这个接口之后,spring在创建这个对象的过程中,在spring完成调用构造方法创建实例,并依据配置进行注入之后,spring就会调用这个类的postProcessBeforeIntitialzation方法进行一个初始化操作,是通过这个方法中的第一个Object类型bean参数进行传递的,另外一个参数,是这个对象在spring中的id值。在这个方法中通过这两个参数就获取到了这个参数,就可以在方法中对这个实例进行加工了。还要把这个加工好的对象交还给spring,通过参数把这个对象进行处理,交还给spring之后,执行我们配置好的初始化方法,然后将这个对象交给after这个方法,通过这个方法进行一次在加工,加工完毕之后,将这个参数传递个返回给spring。最后在客户处可以通过getBean方法进行获取。


        这就是bean引入了BeanPostProcessor这个技术之后的全部的过程分析。后置处理bean的运行原理分析。
        对于使用者,我们的作用就是让我们的bean实现这样的接口和接口中的方法,返回的值是Object


        具体过程:创建实例-注入-before方法-初始化方法-After方法
        有了这两个方法之后呢,实际的过程中,我们我们极少做初始化操作,所以,我们区分这个之前之后,这两个操作就合二为一的,

        实际上spring的初始操作使用的很少,所以,这个所谓的前后,也就没有什么前后之分了,两个挨着呢,实现其中的一个方法即可,也就是将代码写入到一个方法中就可以了。选谁,选After就可以了。但是啥也不干你也得有一个return  bean得到操作。需要注意的事before这个操作,我们必须return bean对象,这张图使我们必须要理解的内容。

package com.spring;

import com.spring.postBeanProcessor.Catagory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Auther: DaShu
 * @Date: 2021/6/24 21:17
 * @Description:
 */
public class TestPostBeanProcessor {
    @Test
    public void test1(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext1.xml");
        //-----------------------before-----------------------
        //PostBeanProcessorTest{id=10, name='xioajianren'}
        //-----------------------before-----------------------
        //------------------------init-----------------------
        //PostBeanProcessorTest{id=11, name='xiaojianren1'}
        //--------------------------init---------------------
        //---------------------------after-------------------------------
        //PostBeanProcessorTest{id=12, name='xiaojianren2'}
        //---------------------------after-------------------------------
    }
}


package com.spring.postBeanProcessor;

/**
 * @Auther: DaShu
 * @Date: 2021/6/24 21:38
 * @Description:
 */
public class Catagory {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "PostBeanProcessorTest{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    public void init(){
        System.out.println("------------------------init-----------------------");
        System.out.println(this.toString());
        System.out.println("--------------------------init---------------------");
    }

}

package com.spring.postBeanProcessor;

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

/**
 * @Auther: DaShu
 * @Date: 2021/6/24 21:04
 * @Description:
 */
public class PostBeanProcessorTest implements BeanPostProcessor {


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof com.spring.postBeanProcessor.Catagory){
            System.out.println("-----------------------before-----------------------");
            System.out.println(bean.toString());
            ((com.spring.postBeanProcessor.Catagory)bean).setId(11);
            ((com.spring.postBeanProcessor.Catagory)bean).setName("xiaojianren1");
            System.out.println("-----------------------before-----------------------");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("---------------------------after-------------------------------");
        ((com.spring.postBeanProcessor.Catagory)bean).setId(12);
        ((com.spring.postBeanProcessor.Catagory)bean).setName("xiaojianren2");
        System.out.println(bean.toString());
        System.out.println("---------------------------after-------------------------------");
        return bean;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id = "catagory" class = "com.spring.postBeanProcessor.Catagory" init-method="init">
        <property name="id" value="10"/>
        <property name="name" value="xioajianren"/>
    </bean>
    <bean id = "postBeanProcessorTest" class = "com.spring.postBeanProcessor.PostBeanProcessorTest" />

</beans>

2:BeanPostProcessor对于AOP作用

        Spring工厂如何加工创建代理对象

        为什么通过原始对象id获取的是代理对象的id值呢?这是aop的核心原理的第二个问题。        

        Spring的工厂是如何加工和创建这个对象呢?
        在spring创建一个对象的时候,spring的工厂可以通过BeanPostProcessor这个工厂来进一步加工这个对象,我们的当时写的案例非常的简单,创建好对象之后,spring工厂调用,在后置BeanPostProcessor当中对这个bean进行赋值,然后将处理后的bean进行返回,当动态代理结合上beanpostprocessor之后,就可以实现这个通过原始的id返回对应的代理对象,其原理呢就是将这个加工代理对象的方法写入到这个后置处理bean中BeanPostProcessor当中的PostProcessorAfterInization这个方法中,然后将代理对象的地址进行返回即可。
我们知道我们很少做这个初始化操作,所以,这个前置处理和后置处理的位置是挨着的,他们的作用是完全一样的,这样的before我们就不用了,直接将bean对象进行返回,交还给spring即可,然后呢,这个所有加工的代理都写在了后置处理的这个方法中,调用的事Proxy.newProxyInstance()这个方法,这里的实现前边都讲过了,然后将创建好的代理对象交还给spring工厂,这样spring工厂就可以通过id获取的事代理对象,这就是通过原始对象的id值获取的事代理对象的加工。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐