说到 Aop不得不提的就是23种设计模式中的代理模式
代理模式马上就要双十一了,天猫上面的苹果手机又要大卖,其中的中间商又要赚差价!
以上的三句话,就是简单的代理模式。
Java中的代理模式,分为静态代理和动态代理
静态代理创建一个代理类对目标类中的方法进行增强
接口类,不管要不要,先创建一个接口(Spring源码分析 1 中有讲解过)
package com.zhao.aop.staticProxy.Interfaces;
public interface SellPhone {
public int sell();
}
实现类
package com.zhao.aop.staticProxy.Impl;
import com.zhao.aop.staticProxy.Interfaces.SellPhone;
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;
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;
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;
public interface SellPhone {
public int sell();
}
实现类
package com.zhao.aop.staticProxy.Impl;
import com.zhao.aop.staticProxy.Interfaces.SellPhone;
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;
public class ProxyFactory {
SellPhone target = new AppleBatchSellPhone();
public SellPhone getProxyObject() {
SellPhone proxyObject = (SellPhone) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
// 代理对象调用的方法,其根本就是调用 invoke 方法进行逻辑处理
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;
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,上面有它的介绍和使用。(我为了省事,就在码云拉取了),下面是它的使用说明链接
Arthas使用文档https://gitee.com/arthas/arthas/blob/master/README_CN.mdhttps://gitee.com/arthas/arthas/blob/master/README_CN.md
内存中的代理类
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;
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;
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;
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;
public interface Log {
void printLog();
}
实现类
package com.zhao.SpringAopTheory.Target;
import com.zhao.SpringAopTheory.Interfaces.Log;
import java.util.concurrent.TimeUnit;
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;
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;
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
com.zhao.SpringAopTheory.Interfaces.Log
logAdvisor
打印结果
封装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
通过以上对 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
通过扇面代码可知,最核心的功能都是在 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 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
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();
public ObjenesisCglibAopProxy(AdvisedSupport config) {
super(config);
}
@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
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
这里的 CglibMethodInvocation 类继承了 ReflectiveMethodInvocation 类,CglibMethodInvocation.procceed() 实际是调用了父类 ReflectiveMethodInvocation.procceed() 方法。



