您的位置:首页 > 其它

动态代理

2018-03-24 10:22 363 查看
动态代理可以不修改源代码的前提下,对目标方法进行增强

JDK自带的动态代理实现,需要让目标类和增强类都实现同一个接口,目标对象和代理对象是平级关系.

而cglib的动态代理实现是基于继承关系的,目标对象是代理对象的父类



jdk动态代理

给出一个目标接口和一个目标实现类

package com.cuixiaoming.proxy.jdk;

public interface TargetInterface {
void targetMethod();
}


package com.cuixiaoming.proxy.jdk;

public class Target implements TargetInterface{
public void targetMethod(){
System.out.println("目标方法运行");
}
}


重头戏来了,看代码

package com.cuixiaoming.proxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyTargetTest {
public static void main(String[] args) {
//0.创建一个目标对象实例
final Target target = new Target();

//1.为目标对象动态生成代理对象,该代理对象是基于接口的
TargetInterface targetProxy=(TargetInterface) Proxy.newProxyInstance(
//参数1:目标参数需要的类加载器
target.getClass().getClassLoader(),
//参数2:目标参数实现的接口
target.getClass().getInterfaces(),

//参数3:InvocationHandler接口的实现类
//这里使用的是匿名内部类的形式,重写了invoke方法
new InvocationHandler() {
//method为当前代理对象调用的方法的字节码对象
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置增强");
//执行目标method
Object invoke = method.invoke(target, args);
System.out.println("后置增强");
return invoke;
}
}
//匿名内部类结束
);
//

//2.测试,代理对象执行被增强后的目标方法
targetProxy.targetMethod();
}
}


cglib的动态代理

应为cglib基于继承关系,不需要继承接口,直接给出需要被增强的目标类

package com.cuixiaoming.proxy.cglib;

public class Target {

public void targetMethod(){
System.out.println("目标方法执行了");
}
}


然后会它进行增强,cglib的步骤看起来比jdk的清晰不少

package com.cuixiaoming.proxy.cglib;

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 TargetProxyTest {

public static void main(final String[] args) {
//0.创建一个实例目标对象
final Target target = new Target();

//1.创建增强器
Enhancer enhancer = new Enhancer();
//2.设置父类
enhancer.setSuperclass(Target.class);
//3.设置回调方法(相当于invoke)
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("前置增强");
Object invoke = method.invoke(target, args);
System.out.println("后置增强");
return invoke;
}
});

//4.创建代理对象
Target targetProxy=(Target) enhancer.create();

//5.测试,让代理对象调用增强之后的目标方法
targetProxy.targetMethod();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态代理