1. JDK
JDK動態代理必須提供接口才可代理
public interface HelloService {
void sayHello1(String name);
String sayHello2(String name);
}
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello1(String name) {
System.out.println("hello1 " + name);
}
@Override
public String sayHello2(String name) {
System.out.println("hello2 " + name);
return name;
}
}
代理對象實現 InvocationHandler 方法
public class JdkProxy implements InvocationHandler {
// 被代理對象
private Object target = null;
/**
* 創建代理對象
* @param target
* @return
*/
public Object bind(Object target) {
this.target = target;
// 參數爲:target 類加載器;target 的方法;實現 InvocationHandler 接口的邏輯代理類,即當前類
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* 代理對象調用方法
* @param proxy 代理對象
* @param method 方法
* @param args 方法參數
* @return 代理調用方法結果
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理前");
// 調用方法,參數是target不是proxy,因爲target中才有具體的方法實現,proxy中沒有
Object obj = method.invoke(target,args);
System.out.println("代理後");
return obj;
}
}
JDK動態代理測試:
@Test
public void jdkProxyTest(){
JdkProxy jdkProxy = new JdkProxy();
// 創建代理對象
HelloService proxy = (HelloService)jdkProxy.bind(new HelloServiceImpl());
// 調用方法
proxy.sayHello1("jdk1");
String sayHello2Return = proxy.sayHello2("jdk2");
System.out.println("sayHello2Return " + sayHello2Return);
}
測試結果:
代理前
hello1 jdk1
代理後
代理前
hello2 jdk2
代理後
sayHello2Return jdk2
2. CGLIB
CGLIB動態代理只需要非抽象類即可代理
public class HelloServiceImpl {
public void sayHello1(String name) {
System.out.println("hello1 " + name);
}
public String sayHello2(String name) {
System.out.println("hello2 " + name);
return name;
}
}
代理對象實現 MethodInterceptor 接口
public class CglibProxy implements MethodInterceptor {
/**
* 生成cglib代理對象
* @param cls
* @return
*/
public Object getProxy(Class cls){
// cglib 增強類對象
Enhancer enhancer = new Enhancer();
// 設置增強類型
enhancer.setSuperclass(cls);
// 定義代理邏輯對象,即實現 MethodInterceptor 接口的對象
enhancer.setCallback(this);
return enhancer.create();
}
/**
* 代理邏輯方法
* @param o 代理對象
* @param method 方法
* @param objects 方法參數
* @param methodProxy 方法代理
* @return 代理邏輯返回
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("代理前");
Object returnObj = methodProxy.invokeSuper(o, objects);
System.out.println("代理後");
return returnObj;
}
}
CGLIB動態代理測試:
@Test
public void cglibProxyTest(){
CglibProxy cglibProxy = new CglibProxy();
HelloServiceImpl helloServiceImpl = (HelloServiceImpl) cglibProxy.getProxy(HelloServiceImpl.class);
helloServiceImpl.sayHello1("cglib");
String returnObj = helloServiceImpl.sayHello2("cglib");
System.out.println(returnObj);
}
測試結果:
代理前
hello1 cglib
代理後
代理前
hello2 cglib
代理後
cglib