JDK动态代理:是java原生的代理技术,是基于接口的动态代理技术
cglib代理:基于父类的动态代理技术;类似在运行期间给目标对象动态生成一个子类,由于是目标对象的子类,就能非常好的完成动态代理;在高版本的spring-cord包中会内置cglib包
这种动态代理的技术就是AOP的底层实现
实现JDK动态代理
目标对象
public class Target {
public void save() {
System.out.println("Target的save方法执行...");
}
}
增强对象
public class Advice{
public void before() {
System.out.println("before方法执行....");
}
public void after() {
System.out.println("after方法执行....");
}
}
动态代理实现
@Test
public void test() {
//目标对象,自定义类
Target target = new Target();
//增强对象,自定义类
final Advice advice = new Advice();
//进行jdk动态代理,返回值就是动态代理对象,使用目标对象继承的接口进行接收
TargetInterface targetInterface = (TargetInterface) Proxy.newProxyInstance(
// 目标资源对象类加载器
target.getClass().getClassLoader(),
// 获取目标对象的接口数组,应为java是单继承多实现
target.getClass().getInterfaces(),
// 目标对象的调的方法
new InvocationHandler(){
/**
* 代理对象的任何方法,实际执行都是方法调对象进行实现
* 所谓的增强就是在调方法的前后再一次的调用方法或是进行一些小改动
* 在没有做一些判断前,会将目标兑现的所有方法进行一个增强
* @param proxy 目标对象
* @param method 当前执行的方法
* @param args 执行方法的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
// 在调用目标对象之前执行方法
advice.before();
// 目标对象的调的方法,
// 注:方法调对象对象要是已经创建好的对象,不能使用方法提供的proxy对象,否则会进入循环递归状态
Object invoke = method.invoke(target, args);
// 在调用目标对象之后执行方法
advice.after();
return invoke;
}
}
);
// 使用动态代理对象调用方法
targetInterface.save();
}
注:在invoke方法中进行对象调方法时,使用的对象要是在此之前创建好的一个对象,不能使用方法形参的Object对象,使用会进行无限递归中
cglib动态代理
代码实现
@Test
public void test1() {
// 目标对象
Target target = new Target();
// 增强对象
final Advice advice = new Advice();
// 返回值就是动态代理对象
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(Target.class);
// 进行增强
enhancer.setCallback(new MethodInterceptor(){
@Override
public Object intercept (Object o,Method method,Object[] objects,MethodProxy methodProxy) throws Throwable{
advice.before();
//执行目标方法
Object invoke = method.invoke(target,args);
advice.after();
return invoke;
}
});
//创建代理对象
Target t = (Target) enhancer.create();
//执行方法
t.save();
}