-
概述
Spring支持三种aop的配置方式,分别是手动配置,自动命名空间配置,自动注解配置 -
生成代理对象的原理
三种aop生成原理其实都是一样的,在spring中使用实现的代码也是一套的。原理都是通过添加一个AbstractAutoProxyCreator的BeanPostProcessor, 然后我们知道BeanPostProcessor会被提前实例化,而且在一个普通对象被创建后(依赖注入完成,开始初始化),会回调BeanPostProcessor接口方法。而代理的生成就是在回调BeanPostProcessor的applyBeanPostProcessorsAfterInitialization方法时生成的,AbstractAutoProxyCreator重写了这个方法,去直接实现生成代理对象,然后返回添加到容器中。代码如下:
参考资料:
(一)Spring源码分析IOC流程图上
(二)Spring源码分析IOC流程图下 -
手动配置实例
所谓手动就是指手动配置一个AbstractAutoProxyCreator,在AbstractAutoProxyCreator配置切点表达式和通知,这样匹配到切点表达式的bean就会在BeanPostProcessor回调的时候将bean转换为代理对象,然后添加到容器中,没匹配到的就直接返回原来创建好的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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--注册被代理对象--> <bean id="userService" class="model.aop.UserServiceImpl"/> <!--注册advice 通知--> <bean id="logArgsAdvice" class="model.aop.LogArgsAdvice"/> <!--根据方法名进去定位,来定位哪些方法要进行增强,当然前提是这个方法的类是个代理类--> <bean id="logArgsAdviceAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice" ref="logArgsAdvice"/> <property name="mappedNames" value="queryUser"/> </bean> <!--BeanNameAutoProxyCreator和ProxyFactoryBean不同 1.不需要配置 proxyInterfaces和 target,因为这个不是针对一个类或者对象做处理的 --