说到 Aop不得不提的就是23种设计模式中的代理模式
代理模式
马上就要双十一了,天猫上面的苹果手机又要大卖,其中的中间商又要赚差价!
以上的三句话,就是简单的代理模式。
Java中的代理模式,分为静态代理和动态代理
静态代理
创建一个代理类对目标类中的方法进行增强
接口类,不管要不要,先创建一个接口(Spring源码分析 1 中有讲解过)
package com.zhao.aop.staticProxy.Interfaces;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 12:54
* @Description: 苹果工厂买手机
*/
public interface SellPhone {
public int sell();
}
实现类
package com.zhao.aop.staticProxy.Impl;
import com.zhao.aop.staticProxy.Interfaces.SellPhone;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 12:56
* @Description: 苹果工厂批量卖手机
*/
public class AppleBatchSellPhone implements SellPhone {
@Override
public int sell() {
System.out.println("苹果官方批量售价:5799 元");
return 5799;
}
}
代理类
package com.zhao.aop.staticProxy.proxy;
import com.zhao.aop.staticProxy.Impl.AppleBatchSellPhone;
import com.zhao.aop.staticProxy.Interfaces.SellPhone;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 12:59
* @Description: 天猫代理
*/
public class TmallProxy {
private SellPhone sellPhone = new AppleBatchSellPhone();
public void sell(){
System.out.println("天猫平台赚取 349 元 代理费用");
int orginalPrice = sellPhone.sell();
System.out.println("天猫售价 "+ (orginalPrice +349));
}
}
憨憨赵类
package com.zhao.aop.staticProxy.Test;
import com.zhao.aop.staticProxy.proxy.TmallProxy;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 13:04
* @Description: 憨憨赵 在天猫平台买手机
*/
public class Clint {
public static void main(String[] args) {
TmallProxy proxy = new TmallProxy();
proxy.sell();
}
}
打印结果
JDK动态代理
与静态代理不同,静态代理是定义好代理类后,由类加载器加载至内存中运行,动态代理类是在内存中生成,通过 newProxyInstance 方法来获取代理对象
接口类,不管要不要先创建一个接口(Spring源码分析 1 中有讲解过)
package com.zhao.aop.Jdk_proxy.Interfaces;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 12:54
* @Description: 苹果工厂买手机
*/
public interface SellPhone {
public int sell();
}
实现类
package com.zhao.aop.staticProxy.Impl;
import com.zhao.aop.staticProxy.Interfaces.SellPhone;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 12:56
* @Description: 苹果工厂批量卖手机
*/
public class AppleBatchSellPhone implements SellPhone {
@Override
public int sell() {
System.out.println("苹果官方批量售价:5799 元");
return 5799;
}
}
代理工厂类
package com.zhao.aop.Jdk_proxy.Factory;
import com.zhao.aop.Jdk_proxy.Impl.AppleBatchSellPhone;
import com.zhao.aop.Jdk_proxy.Interfaces.SellPhone;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 14:19
* @Description: 创建代理对象的工厂类
*/
public class ProxyFactory {
SellPhone target = new AppleBatchSellPhone();
/**
* 获取代理对象的方法,父类引用指向子类实现,多态
* ClassLoader loader 类加载器,用于加载代理类,可以通过目标对象获取类加载器。代理类是程序运行过程中动态的在内存中生成的类,生成的类如果想运行就得先加载
* Class<?>[] interfaces 代理类实现的接口的字节码对象
* InvocationHandler h 代理对象的调用处理程序,它是一个接口,需要用它的实现类(下文的匿名内部类)实现
*
* @return
*/
public SellPhone getProxyObject() {
SellPhone proxyObject = (SellPhone) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
// 代理对象调用的方法,其根本就是调用 invoke 方法进行逻辑处理
/**
*
* @param proxy 代理对象,和proxyObject是同一个对象,在本方法中基本不用
* @param method 对接口中方法进行封装的 method 对象
* @param args 调用方法的实际参数
* @return 就是方法的返回值
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("天猫平台赚取 349 元 代理费用");
// 执行目标对象的方法,返回的是方法的返回值,(如果对这里不懂,反射没学好)
int price = (Integer) method.invoke(target, args);
System.out.println("天猫售价 " + (price + 349));
return price;
}
}
);
return proxyObject;
}
}
- 这个代理类是通过 Proxy.newProxyInstance 产生的,返回的是代理对象
- 这个代理类是在内存中动态生成的类,需要类加载器把它加载至内存中
- Jdk的代理类需要有一个接口给代理类实现,通过这个接口接收这个不知名字的代理类,通过接口来调用同样实现接口的目标类的方法
- 代理对象的处理程序,就是代理类的处理逻辑
- 代理类调用的 invoke 方法 和 method.invoke 对象中的 invoke 不是同一个方法,一个是代理类执行逻辑的方法,一个是反射方法对象调用接口中的方法,反射需要传入目标对象
- 其中 args 表示方法参数
- 代理类的 invoke 返回值是方法的返回值
憨憨赵类
package com.zhao.aop.Jdk_proxy.Test;
import com.zhao.aop.Jdk_proxy.Factory.ProxyFactory;
import com.zhao.aop.Jdk_proxy.Interfaces.SellPhone;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 15:02
* @Description: 憨憨赵
*/
public class Client {
public static void main(String[] args) {
// 获取代理对象
// 1. 创建代理类工厂对象
ProxyFactory proxyFactory = new ProxyFactory();
// 2. 使用 proxyFactory 对象的方法获取代理对象
SellPhone proxyObject = proxyFactory.getProxyObject();
// 3. 调用销售手机的方法
proxyObject.sell();
// 4. 打印代理类的包名
System.out.println(proxyObject.getClass()); // class com.sun.proxy.$Proxy0
// 5. 无限循环,一睹代理类的真正面目
while (true){}
}
}
打印结果
Jdk动态代理类写完了,但是始终没见到它的样子,所以感觉还是有点飘渺。因为它是在内存中动态生成的。想见庐山真面目,还需借助工具实现。
就是Arthas,它
是Alibaba开源的Java诊断工具,在 gitHub上面搜 Arthas,上面有它的介绍和使用。(我为了省事,就在码云拉取了)
,下面是它的使用说明链接
内存中的代理类
package com.zhao.aop.Jdk_proxy.Factory;
import com.zhao.aop.Jdk_proxy.Interfaces.SellPhone;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements SellPhone {
private static Method m3;
// 有参构造创建代理类对象,把 invocationHandler 作为参数传递给父类 Proxy。这个接口的具体实现就是那个匿名内部类
// Proxy.newProxyInstance 的第三个参数,第一个参数把代理类送至方法区,第二个参数表明实现的接口,第三个参数就是它了,最终赋值给 Proxy 中属性 h
public $Proxy0(InvocationHandler invocationHandler) {
super(invocationHandler);
}
// 这个类实现了 SellPhone,编译看左边,运行看右边。所以最终调用的是 代理类中的 sell() 方法
public final int sell() {
// 它又在当前类中找 h 属性,当前类没找到,到父类中找到了,于是调用了 父类属性中的 invoke 方法
return (Integer) this.h.invoke(this, m3, null);
}
static {
// 加载接口的全限定类名,获取方法对象(接口中的sellMethod对象),将方法对象赋值给 m3。没理解这段代码的,反射没学好
m3 = Class.forName("com.zhao.aop.Jdk_proxy.Interfaces.SellPhone").getMethod("sell", new Class[0]);
}
}
public class Proxy{
protected InvocationHandler h;
}
代理类 ($Proxy0) 实现了 SellPhone 接口,这也就印证了我们之前说的真实类和代理类实现了相同的接口。
代理类 ($Proxy0)将我们提供的匿名内部类对象传递给了父类。
综上所述,Jdk动态代理的执行流程是
- 在测试类中通过代理对象调用 sell() 方法
- 根据多态的特性,执行的是代理类($Proxy0)中的 sell() 方法
- 代理类($Proxy0)中的 sell() 方法又调用了 InvocationHandler接口的子实现类中的 invoke 方法
- invoke 方法通过反射执行了真正对象所属类(AppleBatchSellPhone)中的sell() 方法
以上是Jdk中原生的动态代理,但是这有一个弊端,就是被代理的类没有实现接口该怎么办?
这就要用到我们另外一种技术 CgLib 动态代理
CgLib 动态代理
基于目标类创建的子类
目标类
package com.zhao.aop.Cglib_proxy;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 17:33
* @Description: 苹果工厂批量卖手机
*/
public class AppleBatchSellPhone {
public int sell() {
System.out.println("苹果官方批量售价:5799 元");
return 5799;
}
}
工厂类
package com.zhao.aop.Cglib_proxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 17:35
* @Description:
*/
public class ProxyFactory implements MethodInterceptor {
private AppleBatchSellPhone appleBatchSellPhone = new AppleBatchSellPhone();
public AppleBatchSellPhone getProxyObject(){
// 创建 Enhancer 对象,类似于 JDK 代理中的 Proxy 类
Enhancer enhancer = new Enhancer();
// 设置父类的字节码对象
enhancer.setSuperclass(AppleBatchSellPhone.class);
// 设置回调函数
enhancer.setCallback(this);
// 创建代理对象
AppleBatchSellPhone apple = (AppleBatchSellPhone) enhancer.create();
return apple;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("天猫平台赚取 349 元 代理费用");
// 执行目标对象的方法,返回的是方法的返回值,(如果对这里不懂,反射没学好)
int price = (Integer) method.invoke(appleBatchSellPhone, objects);
System.out.println("天猫售价 " + (price + 349));
return price;
}
}
测试
package com.zhao.aop.Cglib_proxy;
/**
* @Auther: HackerZhao
* @Date: 2021/10/22 17:42
* @Description: 憨憨赵
*/
public class Client {
public static void main(String[] args) {
ProxyFactory p = new ProxyFactory();
AppleBatchSellPhone proxyObject = p.getProxyObject();
proxyObject.sell();
System.out.println(proxyObject.getClass());
while (true){}
}
}
打印结果
使用 Arthas查看生成的代理类
package com.zhao.aop.Cglib_proxy;
import com.zhao.aop.Cglib_proxy.AppleBatchSellPhone;
import java.lang.reflect.Method;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba extends AppleBatchSellPhone
implements Factory {
private boolean CGLIB$BOUND;
public static Object CGLIB$FACTORY_DATA;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static Object CGLIB$CALLBACK_FILTER;
private static final Method CGLIB$sell$0$Method;
private static final MethodProxy CGLIB$sell$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
static void CGLIB$STATICHOOK1() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class<?> clazz = Class.forName("com.zhao.aop.Cglib_proxy.AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba");
Class<?> clazz2 = Class.forName("java.lang.Object");
Method[] methodArray = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, clazz2.getDeclaredMethods());
clazz2 = Class.forName("com.zhao.aop.Cglib_proxy.AppleBatchSellPhone");
CGLIB$sell$0$Method = ReflectUtils.findMethods(new String[]{"sell", "()I"}, clazz2.getDeclaredMethods())[0];
CGLIB$sell$0$Proxy = MethodProxy.create(clazz2, clazz, "()I", "sell", "CGLIB$sell$0");
}
final int CGLIB$sell$0() {
return super.sell();
}
// 子类继承方法
public final int sell() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$BIND_CALLBACKS(this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
Object object = methodInterceptor.intercept(this, CGLIB$sell$0$Method, CGLIB$emptyArgs, CGLIB$sell$0$Proxy);
return object == null ? 0 : ((Number)object).intValue();
}
return super.sell();
}
public static MethodProxy CGLIB$findMethodProxy(Signature signature) {
String string = ((Object)signature).toString();
switch (string.hashCode()) {
case -508378822: {
if (!string.equals("clone()Ljava/lang/Object;")) break;
return CGLIB$clone$4$Proxy;
}
case 1826985398: {
if (!string.equals("equals(Ljava/lang/Object;)Z")) break;
return CGLIB$equals$1$Proxy;
}
case 1913648695: {
if (!string.equals("toString()Ljava/lang/String;")) break;
return CGLIB$toString$2$Proxy;
}
case 1978249942: {
if (!string.equals("sell()I")) break;
return CGLIB$sell$0$Proxy;
}
case 1984935277: {
if (!string.equals("hashCode()I")) break;
return CGLIB$hashCode$3$Proxy;
}
}
return null;
}
public AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba() {
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba appleBatchSellPhone$$EnhancerByCGLIB$$b315daba = this;
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$BIND_CALLBACKS(appleBatchSellPhone$$EnhancerByCGLIB$$b315daba);
}
public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] callbackArray) {
CGLIB$THREAD_CALLBACKS.set(callbackArray);
}
public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] callbackArray) {
CGLIB$STATIC_CALLBACKS = callbackArray;
}
private static final void CGLIB$BIND_CALLBACKS(Object object) {
block2: {
Object object2;
block3: {
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba appleBatchSellPhone$$EnhancerByCGLIB$$b315daba = (AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba)object;
if (appleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$BOUND) break block2;
appleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$BOUND = true;
object2 = CGLIB$THREAD_CALLBACKS.get();
if (object2 != null) break block3;
object2 = CGLIB$STATIC_CALLBACKS;
if (CGLIB$STATIC_CALLBACKS == null) break block2;
}
appleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])object2)[0];
}
}
public Object newInstance(Callback[] callbackArray) {
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$SET_THREAD_CALLBACKS(callbackArray);
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba appleBatchSellPhone$$EnhancerByCGLIB$$b315daba = new AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba();
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$SET_THREAD_CALLBACKS(null);
return appleBatchSellPhone$$EnhancerByCGLIB$$b315daba;
}
public Object newInstance(Callback callback) {
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$SET_THREAD_CALLBACKS(new Callback[]{callback});
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba appleBatchSellPhone$$EnhancerByCGLIB$$b315daba = new AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba();
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$SET_THREAD_CALLBACKS(null);
return appleBatchSellPhone$$EnhancerByCGLIB$$b315daba;
}
public Object newInstance(Class[] classArray, Object[] objectArray, Callback[] callbackArray) {
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba appleBatchSellPhone$$EnhancerByCGLIB$$b315daba;
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$SET_THREAD_CALLBACKS(callbackArray);
Class[] classArray2 = classArray;
switch (classArray.length) {
case 0: {
appleBatchSellPhone$$EnhancerByCGLIB$$b315daba = new AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba();
break;
}
default: {
throw new IllegalArgumentException("Constructor not found");
}
}
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$SET_THREAD_CALLBACKS(null);
return appleBatchSellPhone$$EnhancerByCGLIB$$b315daba;
}
public Callback getCallback(int n) {
MethodInterceptor methodInterceptor;
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$BIND_CALLBACKS(this);
switch (n) {
case 0: {
methodInterceptor = this.CGLIB$CALLBACK_0;
break;
}
default: {
methodInterceptor = null;
}
}
return methodInterceptor;
}
public void setCallback(int n, Callback callback) {
switch (n) {
case 0: {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)callback;
break;
}
}
}
public Callback[] getCallbacks() {
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$BIND_CALLBACKS(this);
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba appleBatchSellPhone$$EnhancerByCGLIB$$b315daba = this;
return new Callback[]{this.CGLIB$CALLBACK_0};
}
public void setCallbacks(Callback[] callbackArray) {
Callback[] callbackArray2 = callbackArray;
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba appleBatchSellPhone$$EnhancerByCGLIB$$b315daba = this;
this.CGLIB$CALLBACK_0 = (MethodInterceptor)callbackArray[0];
}
static {
AppleBatchSellPhone$$EnhancerByCGLIB$$b315daba.CGLIB$STATICHOOK1();
}
}
只需看第一行代码,继承了 AppleBatchSellPhone 这个类
Spring原生Aop的源码分析
这里的原生可能很多人感到不解,我们现在用的大多是 AspectJ 框架实现的Aop,像这种切点表达式 @Aspect @Pointcut("execution(*com.zhao.AspectJ.Target.*.*(..))"),用的就是AspectJ。其实 Spring 也有自己的一套 Aop 实现,不过没有 AspectJ 轻量,所以用的人很少。下面例子
接口
package com.zhao.SpringAopTheory.Interfaces;
/**
* @Auther: HackerZhao
* @Date: 2021/10/21 20:15
* @Description: 定义接口
*/
public interface Log {
/**
* 打印日志
*/
void printLog();
}
实现类
package com.zhao.SpringAopTheory.Target;
import com.zhao.SpringAopTheory.Interfaces.Log;
import java.util.concurrent.TimeUnit;
/**
* @Auther: HackerZhao
* @Date: 2021/10/21 20:17
* @Description: 目标对象
*/
public class Target implements Log {
/**
* 操作方法
*/
@Override
public void printLog() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行一些操作");
}
}
增强
package com.zhao.SpringAopTheory.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Auther: HackerZhao
* @Date: 2021/10/21 20:19
* @Description: 通知
*/
public class LogAroundAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("方法执行开始时间:"+dateFormat.format(new Date()));
invocation.proceed();
System.out.println("方法执行结束时间:"+dateFormat.format(new Date()));
return null;
}
}
测试类
package com.zhao.SpringAopTheory.Test;
import com.zhao.SpringAopTheory.Interfaces.Log;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Auther: HackerZhao
* @Date: 2021/10/21 20:24
* @Description: 测试
*/
public class AopSourceCodeLearningDemo {
public static void main(String[] args) {
//加载配置文件
ApplicationContext app = new ClassPathXmlApplicationContext("spring-sourcecodelearning.xml");
// 获取目标对象
Log target = (Log) app.getBean("proxyFactoryBean");
// 执行目标对象的方法
target.printLog();
}
}
配置文件:spring-sourcecodelearning.xml
<?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:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置通知器,通知器的实现定义了需要对目标对象进行的增强行为-->
<bean id="logAdvisor" class="com.zhao.SpringAopTheory.Advice.LogAroundAdvice"/>
<!--目标对象-->
<bean id="sourceTarget" class="com.zhao.SpringAopTheory.Target.Target"/>
<!--配置AOP代理,封装AOP功能的主要类-->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--AOP代理接口-->
<property name="proxyInterfaces">
<value>
com.zhao.SpringAopTheory.Interfaces.Log
</value>
</property>
<!--需要增强的对象-->
<property name="target">
<ref bean="sourceTarget"/>
</property>
<!--拦截器的名字,即通知器在AOP代理的配置下通过使用代理对象的拦截机制发挥作用-->
<property name="interceptorNames">
<list>
<value>logAdvisor</value>
</list>
</property>
</bean>
</beans>
打印结果
封装Aop主要功能的类是 ProxyFactoryBean
打开 ProxyFactoryBean ,分析源码
package com.zhao;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.framework.ProxyCreatorSupport;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
public class ProxyFactoryBean extends ProxyCreatorSupport
implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {
// 标志通知器链是否已经完成初始化
private boolean advisorChainInitialized = false;
// 单例模式的代理对象
private Object singletonInstance;
@Nullable
private String targetName;
/**
* 创建代理对象的入口
* @return
* @throws BeansException
*/
@Override
@Nullable
public Object getObject() throws BeansException {
// 初始化通知器链
initializeAdvisorChain();
// 如果是单例模式
if (isSingleton()) {
// 返回单例模式的代理对象
return getSingletonInstance();
}
// 如果不是单例模式
else {
......
// 每次创建一个新的代理对象
return newPrototypeInstance();
}
}
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
// 如果通知器链已经被初始化,则直接返回,即通知器链只在第一次获取代理对象的时生成
if (this.advisorChainInitialized) {
return;
}
// 如果 ProxyFactoryBean 中配置的通知器/拦截器的名字不为空
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
......
// 遍历通知器链,向容器添加通知器
for (String name : this.interceptorNames) {
......
// 如果通知器是全局的
if (name.endsWith(GLOBAL_SUFFIX)) {
......
// 向容器中添加全局通知器
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
// 如果通知器不是全局的
else {
Object advice;
// 如果通知器是单态模式
if (this.singleton || this.beanFactory.isSingleton(name)) {
// 从容器获取单态模式的通知器
advice = this.beanFactory.getBean(name);
}
// 如果通知器是单态模式
else {
// 创建一个新的通知器对象
advice = new PrototypePlaceholderAdvisor(name);
}
// 添加通知器到通知器链上
addAdvisorOnChainCreation(advice, name);
}
}
}
// 设置通知器链已初始化标识
this.advisorChainInitialized = true;
}
// 返回单例模式的代理对象
private synchronized Object getSingletonInstance() {
// 如果单例模式的代理对象还未被创建
if (this.singletonInstance == null) {
// 获取代理的目标源
this.targetSource = freshTargetSource();
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
Class<?> targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
// 设置被代理的接口
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
// 初始化共享的单例模式对象
super.setFrozen(this.freezeProxy);
// 调用 ProxyFactory 生成代理对象调用
this.singletonInstance = getProxy(createAopProxy());
}
// 返回已创建的单例对象
return this.singletonInstance;
}
// 获取一个新的原型模式的代理对象
private synchronized Object newPrototypeInstance() {
// 创建一个 ProxyCreatorSupport 对象
ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
// The copy needs a fresh advisor chain, and a fresh TargetSource.
TargetSource targetSource = freshTargetSource();
// 从当前对象中复制 AOP 的配置,为了保持原型模式对象的独立性
copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
// 设置代理接口
Class<?> targetClass = targetSource.getTargetClass();
if (targetClass != null) {
copy.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
}
copy.setFrozen(this.freezeProxy);
if (logger.isTraceEnabled()) {
logger.trace("Using ProxyCreatorSupport copy: " + copy);
}
// 生成代理对象调用 ProxyCreatorSupport.createAopProxy()
return getProxy(copy.createAopProxy());
}
// 无论是单例还是原型模式,最终都是通过 getProxy() 方法获取代理对象的
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);
}
}
通过以上对 getSingletonInstance() 方法和 newPrototypeInstance() 方法的注释可以发现,这两个方法都会调用 ProxyCreatorSupport.createAopProxy() 方法,ProxyCreatorSupport 类的核心代码如下
package com.zhao;
import org.springframework.aop.framework.*;
@SuppressWarnings("serial")
public class ProxyCreatorSupport extends AdvisedSupport {
// AOPProxy 工厂
private AopProxyFactory aopProxyFactory;
// 当第一个 AOPProxy 代理对象被创建时,设置为 true
private boolean active = false;
// 默认使用 DefaultAopProxyFactory 的作用 AopProxyFactory
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
// 创建 AopProxy 代理类的入口
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 调用 DefaultAopProxyFactory 的创建 AopProxy 代理的方法
return getAopProxyFactory().createAopProxy(this);
}
private void activate() {
this.active = true;
for (AdvisedSupportListener listener : this.listeners) {
listener.activated(this);
}
}
}
createAopProxy(this) 可以看出 AopProxy 对象是在 DefaultAopProxyFactory 类的 createAopProxy() 方法中生成的, DefaultAopProxyFactory.createAopProxy() 方法的代码如下
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 如果 Aop 使用显式优化,或者配置了目标类,或者只使用 Spring 支持的代理接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 获取 Aop 配置的目标类
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
// 如果配置的 AOP 目标类是接口,则使用 JdkDynamicAopProxy 生成代理对象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则使用 ObjenesisCglibAopProxy 生成代理对象
return new ObjenesisCglibAopProxy(config);
}
// 如果不满足 if 条件则使用 JdkDynamicAopProxy 生成代理对象
else {
return new JdkDynamicAopProxy(config);
}
}
}
Jdk动态代理只针对接口起作用,Spring中通过 JdkDynamicAopProxy 类使用 JDK 动态代理创建 AopProxy 对象,JdkDynamicAopProxy 类的定义如下
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
// 获取代理类接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 查找代理目标的接口中是否定义 equals() 和 hashCode() 方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 使用 JDK 的动态代理机制创建 AOP 代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
// 查找代理的接口是否定义 equals() 和 hashCode() 方法
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
// 遍历代理接口
for (Class<?> proxiedInterface : proxiedInterfaces) {
// 接口中所有声明的方法
Method[] methods = proxiedInterface.getDeclaredMethods();
for (Method method : methods) {
// 如果方法是 equals() 方法,则设置当前对象 equalsDefined 属性
if (AopUtils.isEqualsMethod(method)) {
this.equalsDefined = true;
}
// 如果方法是 hashCode() 方法,则设置当前对象 hashCodeDefined 属性
if (AopUtils.isHashCodeMethod(method)) {
this.hashCodeDefined = true;
}
if (this.equalsDefined && this.hashCodeDefined) {
return;
}
}
}
}
// 因为当前类实现了 InvocationHandler 方法,所以代理对象执行的是实现类(当前类)的 invoke 方法
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
// 获取通知的相关信息
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 如果代理目标对象的接口中没有定义 equals() 方法,且当前调用的方法是 equals() 方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// 调用 JdkDynamicAopProxy 中重写的 equals() 方法
return equals(args[0]);
}
// 如果代理目标对象的接口中没有定义 hashCode() 方法,且当前调用的方法是 hashCode() 方法
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// 调用 JdkDynamicAopProxy 中重写的 hashCode() 方法
return hashCode();
}
......
// 获取目标对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取目标对象方法配置的拦截器(通知器)链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 如果没有配置任何通知
if (chain.isEmpty()) {
// 没有配置通知,使用反射直接调用目标对象的方法,并获取方法的返回值
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
// 如果配置了通知
else {
// 创建 MethodInvocation 对象
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 调用通知器链,沿着通知器链调用所有配置的通知
retVal = invocation.proceed();
}
// 如果方法有返回值,则将代理对象作为方法返回值
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
......
}
}
通过扇面代码可知,最核心的功能都是在 invocation.proceed() 方法中实现的,下面分析 ReflectiveMethodInvocation,代码如下
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
protected final Object proxy;
protected final Object target;
protected final Method method;
protected Object[] arguments = new Object[0];
private final Class<?> targetClass;
@Nullable
private Map<String, Object> userAttributes;
protected final List<?> interceptorsAndDynamicMethodMatchers;
private int currentInterceptorIndex = -1;
protected ReflectiveMethodInvocation(
Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}
@Override
@Nullable
public Object proceed() throws Throwable {
// 如果拦截器链中通知已经调用完毕
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 调用 invokeJoinpoint() 方法
return invokeJoinpoint();
}
// 获取拦截器链中的通知器或通知
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 如果获取的通知器或通知是动态匹配方法拦截器类型
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 动态匹配方法拦截器
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
// 如果匹配成功,调用拦截器的方法
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// 如果不匹配,递归调用 proceed() 方法,直到拦截器链被全部调用为止
return proceed();
}
}
// 如果不是动态匹配方法拦截器,则切入点在构造对象之前进行静态匹配,调用拦截器的方法
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
// 调用对象目标方法
@Nullable
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
}
invokeJoinpoint() 会调用AopUtils.invokeJoinpointUsingReflection() 方法,代码如下
@Nullable
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
throws Throwable {
// Use reflection to invoke the method.
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
// Invoked method threw a checked exception.
// We must rethrow it. The client won't see the interceptor.
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}
可以看到 invokeJoinpointUsingReflection() 方法最终是通过反射调用目标对象的方法
CgLibAopProxy
如果目标类没有实现接口,需要用 CgLib 产生代理对象
ObjenesisCglibAopProxy 类的代码如下
class ObjenesisCglibAopProxy extends CglibAopProxy {
private static final Log logger = LogFactory.getLog(ObjenesisCglibAopProxy.class);
private static final SpringObjenesis objenesis = new SpringObjenesis();
/**
* 调用父构造器
* @param config
*/
public ObjenesisCglibAopProxy(AdvisedSupport config) {
super(config);
}
/**
* 创建代理类并创建代理对象
* @param enhancer
* @param callbacks
* @return
*/
@Override
@SuppressWarnings("unchecked")
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
Class<?> proxyClass = enhancer.createClass();
Object proxyInstance = null;
if (objenesis.isWorthTrying()) {
try {
proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
}
catch (Throwable ex) {
logger.debug("Unable to instantiate proxy using Objenesis, " +
"falling back to regular proxy construction", ex);
}
}
if (proxyInstance == null) {
// Regular instantiation via default constructor...
try {
Constructor<?> ctor = (this.constructorArgs != null ?
proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
proxyClass.getDeclaredConstructor());
ReflectionUtils.makeAccessible(ctor);
proxyInstance = (this.constructorArgs != null ?
ctor.newInstance(this.constructorArgs) : ctor.newInstance());
}
catch (Throwable ex) {
throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
"and regular proxy instantiation via default constructor fails as well", ex);
}
}
((Factory) proxyInstance).setCallbacks(callbacks);
return proxyInstance;
}
}
从代码可以看出 ObjenesisCglibAopProxy 继承了 CglibAopProxy,Objenesis 是一个轻量级的 Java 库,作用是绕过构造器创建一个实例。因此分析的重点还是 CglibAopProxy 类。
package com.zhao.SpringNativeImpl;
class CglibAopProxy implements AopProxy, Serializable {
@Override
public Object getProxy() {
return getProxy(null);
}
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}
try {
// 获取目标对象
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
// 将目标对象本身作为基类
Class<?> proxySuperClass = rootClass;
// 检查获取到的目标类是否由 CgLib 产生的
if (ClassUtils.isCglibProxyClass(rootClass)) {
// 如果目标类是由 CgLib 产生的,获取目标对象的基类
proxySuperClass = rootClass.getSuperclass();
// 获取目标类的接口
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
// 将目标类的接口添加到容器 AdvisedSupport 中
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// 效验代理基类
validateClassIfNecessary(proxySuperClass, classLoader);
// 配置 CgLib 的 Enhancer 类,Enhancer 是CgLib 中的主要操作类
Enhancer enhancer = createEnhancer();
......
// 设置 enhancer 的接口
enhancer.setSuperclass(proxySuperClass);
// 设置接口
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
// 设置 enhancer 的回调方法
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
// 设置 enhancer 的回调类型
enhancer.setCallbackTypes(types);
// 创建代理对象,由于该方法被子类重写了,因此会调用子类重写后的方法
return createProxyClassAndInstance(enhancer, callbacks);
}
......
}
}
CgLib 的运行需要配合回调方法,实现 MethodInterceptor 接口,在 CglibAopProxy 中也是一样,下面分析获取回调方法 getCallbacks( ) 的代码
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// 根据 AOP 配置创建一个动态通知拦截器,CgLib 创建的动态代理会自动调用
// DynamicAdvisedInterceptor 类的 intercept 方法对目标对象进行拦截处理
Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised);
// 创建目标分发器
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ?
new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
}
else {
targetInterceptor = isStatic ?
new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = isStatic ?
new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.SerializableNoOp();
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // 普通通知
targetInterceptor, // invoke target without considering advice, if optimized
new CglibAopProxy.SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new CglibAopProxy.EqualsInterceptor(this.advised),
new CglibAopProxy.HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// 如果目标对象是静态的,并且通知链被冻结,则使用优化 Aop 调用,直接对方法使用固定的通知链
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new CglibAopProxy.FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}
// 将固定回调和主要回调复制到回调数组中
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
// 如果目标不是静态的,或者通知器链不被冻结,则使用 Aop 主要的通知
else {
callbacks = mainCallbacks;
}
return callbacks;
}
CgLib 回调拦截器链的代码
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取目标对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取 AOP 配置的通知
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 如果没有配置通知
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 直接调用目标对象的方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
// 如果配置了通知
else {
// 通过 CglibMethodInvocation 来启动配置的通知
retVal = new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
// 获取目标对象对象方法的回调结果,如果有必要则封装为代理
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
......
}
}
这里的 CglibMethodInvocation 类继承了 ReflectiveMethodInvocation 类,CglibMethodInvocation.procceed() 实际是调用了父类 ReflectiveMethodInvocation.procceed() 方法。