深入理解BeanPostProcessor接口

BeanPostProcessor提供了在bean初始化之前和之后插入自定义逻辑的能力。与BeanFactoryPostProcessor的区别是处理的对象不同,BeanFactoryPostProcessor是对beanfactory进行处理,BeanPostProcessor是对bean进行处理。


BeanPostProcessor接口概述

Spring中使用了许多BeanPostPorcessor来处理回调,在了解Spring Bean的生命周期时,会发现充斥着许多BeanPostProcessor的方法执行.了解这些Spring框架的BeanPostProcessor,来试图找到一些AOP有关的线索。

从整体的视角来看,Spring IoC支持以注解驱动的方式来创建与管理对象,那么Spring AOP是用来代理对象的,没有了对象,空谈Spring AOP是无意义的。在前面分析getBean的流程中,我们也找到了一些AOP的蛛丝马迹,下面我们从BeanPostcessor的角度来看看在Bean的生命周期中一些关键的后置处理器。

在这里插入图片描述


在IOC过程中引入AOP

AOP核心实现-动态代理。大家都知道,Spring AOP是基于动态代理实现的,那么什么是动态代理呢,其实就是一种通过实现或继承的方式对原来类的某些功能进行增强的技术,JDK中动态代理的实现方式是这样的:


Class[] interfaces = bean.getClass().getInterfaces();
Object obj = Proxy.newProxyInstance(AopPostProcessor.class.getClassLoader(), interfaces, new AopInvocationHandler(bean));

public class AopInvocationHandler implements InvocationHandler {

    Object target;

    public AopInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("before proxy");

        Object obj = method.invoke(target, args);

        System.out.println("after proxy");

        return obj;
    }

很简单,也很直观,其实也不过是通过InvocationHandler在方法执行前后增加了一些处理过程。而基于Cglib的也是一样:

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(AopBean.class);
enhancer.setCallback(new MethodInterceptor() {

     @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

         System.out.println("before");
         Object obj = methodProxy.invokeSuper(o, objects);
         System.out.println("after");
         return obj;
     }
  });
  Object enObj = enhancer.create();
 ((AopBean)enObj).getName();

这就是动态代理,如果想要对哪个类进行增强,直接通过这两种方式就可以了,但是为什么还要出一个面向切面编程呢?那和IOC又有什么关系呢?我们接下来就要想了,要对单个的类增强用以上方式是比较容易了,但是如果是批量的呢?我们总不能每一个类都写一个代理吧!那么我们就需要一种批量处理的方式了,其实说到批量处理,用模板模式来解决是最适合的方式了。但是在Spring框架中所有的类及Bean实例都是由Spring IOC来管理的,那么这种批量的模板式的处理也必须要基于Spring IOC来完成了。

AOP切面实现-BeanPostProcessor。其实前面在分析Spring IOC源码时有一个方法已经标记出来时让大家记住的,就是postProcessBeanFactory,并且告诉了大家这是自定义扩展的位置,而今天AOP的接入就是依赖这种方式实现的。在Spring中有一个接口BeanPostProcessor, 我们只要实现了这个接口中的方法postProcessBeforeInitialization或postProcessAfterInitialization,在方法中创建Bean的代理并且以李代桃僵的方式用代理对象替换了原来的实际对象,那么就会被自动注册为Bean,这样我们通过Spring IOC获取Bean对象并且调用的时候,实际调用的就是代理对象,增强功能自然也就实现了。要形成切面,其实就是对多个Bean的批量代理,因为每次初始化的时候都会自动调用postProcessBeforeInitialization或postProcessAfterInitialization,我们只要控制好Bean的范围就可以形成一个个的切面了

综上所述,我们通过实现BeanPostProcessor接口实现切面;通过在切面中的动态代理返回代理对象实现功能增强。Spring面向切面编程也就可以实现了。当然还会有许多其他的辅助过程,但是只要记住在哪里形成切面和如何通过动态代理增强特定功能这两点核心就可以了。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring IOC(Inversion of Control,控制反转)是Spring框架的核心特性之一,它通过将对象的创建和依赖关系的管理交给Spring容器来实现,降低了组件之间的耦合性。下面是Spring IOC的一些深入理解和使用方法: 1. 配置方式:Spring IOC提供了多种配置方式,包括XML配置、注解配置和Java配置。XML配置是最传统和常用的方式,可以通过在XML文件中定义bean来描述对象及其依赖关系;注解配置使用注解来标识对象及其依赖关系,更加简洁和方便;Java配置则是通过Java类来定义对象及其依赖关系。 2. Bean的定义:在Spring IOC中,对象称为Bean。Bean的定义包括类名、属性、构造函数参数等信息。在XML配置中,可以使用<bean>标签来定义Bean;在注解配置中,可以使用@Component等注解来标识Bean。 3. 依赖注入:Spring IOC通过依赖注入(Dependency Injection,DI)来管理对象之间的依赖关系。依赖注入可以通过构造函数注入、Setter方法注入和字段注入来实现。当Spring容器创建一个Bean时,会自动将其依赖的其他Bean注入进来。 4. 生命周期管理:Spring IOC容器负责管理Bean的生命周期。在Bean生命周期中,容器会在适当的时机调用Bean的初始化方法和销毁方法。可以通过在Bean类中定义@PostConstruct和@PreDestroy等注解方法来指定初始化和销毁方法。 5. AOP支持:Spring IOC提供了对面向切面编程(AOP)的支持。可以通过配置切面和增强器,将一些横切关注点(如日志、事务管理等)从业务逻辑中剥离出来,实现更好的代码解耦和复用。 6. 容器扩展点:Spring IOC容器提供了一些扩展点,可以通过实现相应的接口来对容器的行为进行定制。例如,可以实现BeanPostProcessor接口来在对象创建和初始化的过程中添加自定义逻辑。 总之,深入理解和使用Spring IOC可以帮助开发者更好地利用Spring框架的优势,实现松耦合、可测试、可扩展的应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值