jdk動態(tài)代理
jdk自帶,必須有接口的類才可以使用該代理
//繼承InvocationHandler實(shí)現(xiàn)invoke
public class DynamicProxy implements InvocationHandler {
private Object target ;
public DynamicProxy(Object target ) {
this.target=target;
}
//每次創(chuàng)建代理對象就會執(zhí)行下面的方法,proxy是本代理對象,method是當(dāng)前執(zhí)行的方法,可以在這里過濾獲取目標(biāo)方法,參數(shù)三是該方法的參數(shù)
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(target, args);//調(diào)用invoke,傳入目標(biāo)對象和參數(shù)進(jìn)行執(zhí)行之前的方法
after();
return result;
}
private void after() {
System.out.println("之前");
}
private void before() {
System.out.println("之后");
}
}
使用
public static void main(String[] args) {
Hello helloImpl = new HelloImpl();
DynamicProxy dynamicProxy = new DynamicProxy(helloImpl);
//創(chuàng)建代理對象,使用到靜態(tài)工具方法Proxy.neweProxyInstace(類加載器,接口類,增強(qiáng)類);返回值為代理的對象
Hello helloProxy = (Hello) Proxy.newProxyInstance(helloImpl.getClass().getClassLoader(), helloImpl.getClass().getInterfaces(), dynamicProxy);
helloProxy.say("zhangsan");
}
cglib
無需接口都可使用該代理
public class CGLibProxy implements MethodInterceptor {
/***
* 快速創(chuàng)建動態(tài)代理對象
* @param cls 需要代理的字節(jié)碼對象
* @return 代理對象
*/
public <T> T getProxy(Class<T> cls){
return (T) Enhancer.create(cls,this);
}
/***
* 攔截的方法
* @param obj 原對象
* @param method 源對象中的方法
* @param args 源方法中的參數(shù)
* @param proxy 方法代理
*
* @return 返回代理對象
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
before();
//執(zhí)行原方法
Object result = proxy.invokeSuper(obj, args);
after();
return result;
}
private void after() {
System.out.println("之前");
}
private void before() {
System.out.println("之后");
}
}
使用
public static void main(String[] args) {
CGLibProxy cgLibProxy = new CGLibProxy();
HelloImpl helloProxy = cgLibProxy.getProxy(HelloImpl.class);
helloProxy.say("張三");
}