JDK动态代理
必须提供接口才可以使用,但是在某些环境下,接口这个条件是无法满足的,这时候JDK动态代理
就无法使用了,只能采取第三方技术,比如CGLIB动态代理
技术。它的最大的优势就是不需要提供接口,只要一个非抽象类就可以实现动态代理。
第一步:定义真实服务类
package com.lemon.designmode.bean;
/**
* @author lemon
* @date 2018/2/11 下午12:37
*/
public class CglibTarget {
public void sayHello() {
System.out.println("向CGLIB问好...");
}
}
这个真实服务类可以不需要实现任何接口。
第二步:动态代理绑定和代理逻辑实现
这里将获取代理对象和对真实服务类进行代理的逻辑代码集中在一个类中,实现代理逻辑的类需要实现MethodInterceptor
接口中的intercept
方法。
package com.lemon.designmode.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @author lemon
* @date 2018/2/11 下午12:28
*/
public class CglibProxyExample implements MethodInterceptor {
/**
* 获取代理对象
*
* @param clazz 真实服务类的Class对象
* @return 代理对象
*/
public Object getProxy(Class clazz) {
// CGLIB增强类
Enhancer enhancer = new Enhancer();
// 设置需要被增强的类型
enhancer.setSuperclass(clazz);
// 设置代理逻辑对象,此对象必须实现MethodInterceptor接口
enhancer.setCallback(this);
return enhancer.create();
}
/**
* 代理的逻辑方法
*
* @param proxy 代理对象
* @param method 代理方法
* @param args 被代理方法的参数
* @param methodProxy 方法代理
* @return 代码逻辑返回
* @throws Throwable 异常
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("进入代理方法");
System.out.println("代理方法调用真实对象之前的逻辑处理");
Object obj = methodProxy.invokeSuper(proxy, args);
System.out.println("代理方法调用真实对象之后的逻辑处理");
return obj;
}
}
这里用了CGLIB
的加强者Enhancer
,通过设置超类的方法(setSuperclass
),然后通过setCallback
方法设置哪个类为它的代理类。其中this
表示当前类对象,也就是说当前类就是逻辑代码的主要类。
第三步:测试CGLIB动态代理
package com.lemon.designmode.test;
import com.lemon.designmode.bean.CglibTarget;
import com.lemon.designmode.proxy.CglibProxyExample;
/**
* @author lemon
* @date 2018/2/11 下午12:46
*/
public class CglibProxyTest {
public static void main(String[] args) {
CglibProxyExample cglibProxyExample = new CglibProxyExample();
CglibTarget proxy = (CglibTarget) cglibProxyExample.getProxy(CglibTarget.class);
proxy.sayHello();
}
}
测试方法运行结果如下:
进入代理方法
代理方法调用真实对象之前的逻辑处理
向CGLIB问好...
代理方法调用真实对象之后的逻辑处理