版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rap_libai/article/details/79020041
一、JDK动态代理
被代理的实现类:
public interface Helloworld {
public void sayHelloworld();
}
public class HelloWorldImpl implements Helloworld {
@Override
public void sayHelloWorld(){
System.out.println("Hello World!");
}
}
实现java.lang.reflect.InvocationHandler接口,它里面定义了一个invoke方法,并提供接口数组用于下挂代理对象代码如下:
public class JdkProxyExample implements InvocationHandler {
//真实对象
private Object target = null;
public Object bind(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入代理逻辑方法");
System.out.println("在调度真实对象之间的服务");
Object obj = method.invoke(target,args);//相当于调用sayHelloWorld
System.out.println("在调度真实对象之后的服务");
return obj;
}
}
第一步,建立代理对象和真实对象的关系。这里用了bind方法来实现
newProxyInstance方法的3个参数:
- 第一个是类加载器,用了target本身的类加载器
- 第二个是把生成的动态代理对象下挂在哪些接口下
- 第三个是定义实现方法的逻辑代理类,this指当前对象,他必须实现invoke方法
第二步,实现代理逻辑方法,invoke方法
invoke的3个参数:
- proxy,代理对象,就是bind生成的对象
- method,当前调度的方法
- args,调度方法的参数
测试JDK动态代理:
public void testJdkProxy(){
JdkProxyExample jdk = new JdkProxyExample();
HelloWorld proxy = (HelloWorld)jdk.bind(new HelloWorldImpl());
proxy.sayHelloWorld();
}
运行结果
进入代理逻辑方法
在调度真实对象之间的服务
Hello World!
在调度真实对象之后的服务
二、CGLIB动态代理
JDK动态代理必须提供接口才能使用,在一些不能提供接口的环境中药使用第三方技术,如CGLIB动态代理。它的优势在于不需要提供接口,只要一个非抽象类就能实现动态代理。
被代理类:
被代理类:
public class HelloWorldImpl{
public void sayHelloWorld(String name){
System.out.println("Hello" + name);
}
}
代理类:
public class CglibProxyExample implements MethodInterceptor {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("调用真实对象前");
//CGLIB反射调用真实对象方法
Object result = methodProxy.invokeSuper(proxy, args);
System.out.println("调用真实对象后");
return result;
}
public Object getProxy(Class<?> cls){
//CGLIB enhancer 增强类对象
Enhancer enhancer = new Enhancer();
//设置增强类型
enhancer.setSuperclass(cls);
//定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
enhancer.setCallback(this);
//生成并返回代理对象
return enhancer.create();
}
}
这里用了CGLIB的加强者Enhancer,通过设置超类方法(setUperclass),然后通过setCallback方法设置哪个类为他的代理类。其中this引用了intercept,然后返回代理对象。
测试:
CglibProxyExample cpe = new CglibProxyExample();
HelloWorldImpl obj = (HelloWorldImpl) cpe.getProxy(HelloWorldImpl.class);//获得代理对象
obj.sayHello("张三");//调用逻辑处理方法
结果:
调用真实对象前
Hello 张三
调用真实对象后