java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring BeanPostProcessor处理器

Spring BeanPostProcessor后处理器源码解析

作者:保持敬畏

这篇文章主要介绍了Spring BeanPostProcessor后处理器源码解析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

Spring后处理器-BeanPostProcessor

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;
public interface BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

创建实现该接口(BeanPsotProcessor)的类,要在配置文件中进行管理

快捷键 ctrl + insert 重写接口方法

package com.example.PostProcessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + ":postProcessBeforeInitialization");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + ":postProcessAfterInitialization");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

测试类代码

package com.example.Test;
import com.example.Service.Impl.UserServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestApplicationContext {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        System.out.println(context.getBean(UserServiceImpl.class));
    }
}

运行结果如下

展示了该后处理器的执行时机 

Before和After执行时机

在Bean实例化过程可以配置相关对于bean对象的操作方法,具体间往期文章:Bean的配置

注册为bean的类

package com.example.Service.Impl;
import com.example.DAO.UserDAO;
import com.example.Service.UserService;
import org.springframework.beans.factory.InitializingBean;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class UserServiceImpl implements UserService, InitializingBean {
    // todo 无参构造方法
    public UserServiceImpl() {
        System.out.println("UserServiceImpl实例化");
    }
    // todo 自定义初始化方法
    public void init() {
        System.out.println("自定义初始化方法init()");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("属性设置之后执行afterPropertiesSet()");
    }
}

实现bean后处理器的类

package com.example.PostProcessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + ":postProcessBeforeInitialization");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + ":postProcessAfterInitialization");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

配置文件

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <bean class="com.example.PostProcessor.MyBeanPostProcessor"></bean>
    <bean id="userService" class="com.example.Service.Impl.UserServiceImpl" init-method="init">
</beans>

测试类

package com.example.Test;
import com.example.Service.Impl.UserServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestApplicationContext {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        System.out.println(context.getBean(UserServiceImpl.class));
    }
}

运行结果

小结

  从上述运行结果来看,首先完成bean对象的创建,然后执行后处理器中的before方法,然后执行属性设置之后的方法,然后执行自定义的初始化方法,最后执行后处理器的after方法

案例

代理类(实现了bean后处理接口)

package com.example.PostProcessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Date;
public class TimeLogBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // todo 使用动态代理对目标bean进行增强,返回proxy对象,进而存储到单例池singletonObjects中
        Object beanProxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), (InvocationHandler) (proxy, method, args) -> {
            // 输出开始时间
            System.out.println("方法" + method.getName() + "开始执行时间" + new Date());
            // 执行目标方法
            Object rs = method.invoke(bean, args);
            // 输出结束时间
            System.out.println("方法" + method.getName() + "结束执行时间" + new Date());
            return rs;
        });
        return beanProxy;// 将增强的bean存入单例池中
    }
}
 

bean对象对应的类

package com.example.Service.Impl;
import com.example.Service.UserService;
public class UserServiceImpl implements UserService {
    public void show() {
        System.out.println("show......");
    }
}

接口类

package com.example.Service;
public interface UserService {
    public void show();
}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean class="com.example.PostProcessor.TimeLogBeanPostProcessor"></bean>
    <bean id="userService" class="com.example.Service.Impl.UserServiceImpl">
    </bean>
</beans>

测试类

package com.example.Test;
import com.example.Service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestApplicationContext {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        UserService UserServiceBean = (UserService) context.getBean(UserService.class);
        UserServiceBean.show();
    }
}
 

运行结果

Bean实例化基本流程图

首先通过Reader读取配置文件,解析bean标签,然后将每个bean标签变成beanDefinition对象存储到beanDefinitionMap中,然后经过所有的BeanFactoryPostProcessor(bean工厂后处理器),再从Map中取出每个beanDefiniton对象,通过反射变成Object对象,创建完对象后,经过beanPoatProcessor中的before方法和after方法(之间还存在bean中的init方法,后面会讲述),最终存入单例池中。 

到此这篇关于Spring BeanPostProcessor后处理器的文章就介绍到这了,更多相关Spring BeanPostProcessor后处理器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文