首先主要元素:
- 目标接口
- 目标对象
- 增强对象
TargetInterface目标接口
package com.cvicse.ump.proxy.jdk;
/**
* 目标接口
*/
public interface TargetInterface {
/**
* 目标方法
*/
public void save();
}
Target目标对象
package com.cvicse.ump.proxy.jdk.impl;
import com.cvicse.ump.proxy.jdk.TargetInterface;
/**
* 目标对象
*/
public class Target implements TargetInterface {
/**
* 目标方法
*/
public void save() {
System.out.println("runing.......");
}
}
Advice增强对象
package com.cvicse.ump.advice;
/**
* 增强对象
*/
public class Advice {
public void before(){
System.out.println("前置增强.....");
}
public void after(){
System.out.println("后置增强.....");
}
}
模拟AOP底层的JDK动态代理
package com.cvicse.test;
import com.cvicse.ump.advice.Advice;
import com.cvicse.ump.proxy.jdk.TargetInterface;
import com.cvicse.ump.proxy.jdk.impl.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class jdkProxyTest {
public static void main(String[] args) {
//创建目标对象
final TargetInterface target=new Target();
//创建增强对象
final Advice advice = new Advice();
//生成动态代理对象
TargetInterface proxy= (TargetInterface) Proxy.newProxyInstance(
target.getClass().getClassLoader(),//目标对象类加载器
target.getClass().getInterfaces(),//目标对象相同的接口字节码对象数组(一个类可以实现多个接口所以是数组)
new InvocationHandler() {
//invoke,当调用代理对象的任何方法,它实质执行的都是这个invoke
//proxy代理对象,method要执行的方法的方法字节码对象,args传递参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//前置增强
advice.before();
//此处invoke是反射的invoke不是回调
//target 执行的目标对象,args 参数
Object invoke = method.invoke(target, args);//执行目标方法
//后置增强
advice.after();
return invoke;
}
} );
//调用动态代理方法
proxy.save();
}
}
这里的写法是耦合死了的,这是因为我们只是模拟,使用AOP的时候代理对象的生成代码是AOP根据配置文件等信息动态生成的。