代理.png
Java靜態(tài)代理 委托類和代理類肩刃,實現(xiàn)共同接口
共同接口:
public interface HelloService {
void sayHello();
}
委托類:
public class Hello implements HelloService{
@Override
public void sayHello() {
System.out.println("hi, this is Hello-Original.");
}
}
代理類:
public class HelloProxy implements HelloService {
private Hello source = new Hello();
@Override
public void sayHello() {
before();
source.sayHello();
after();
}
private void before(){
System.out.println("Before hello, I need prepare something...");
}
private void after(){
System.out.println("After hello, I need conclude something...");
}
}
測試結(jié)果:
public static void main(String[] args) {
HelloProxy helloProxy = new HelloProxy();
helloProxy.sayHello();
}
Before hello, I need prepare something...
hi, this is Hello-Original.
After hello, I need conclude something...
Java動態(tài)代理 通過反射生成代理類
實現(xiàn) InvocationHandler
通過 Proxy.newProxyInstance 構(gòu)建
public class JavaProxyInvocationHandler implements InvocationHandler {
private Object obj;
public JavaProxyInvocationHandler(Object obj){
this.obj = obj;
}
public Object newProxyInstance(){
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("obj invoked before...");
Object result = method.invoke(obj, args);
System.out.println("obj invoked after...");
return result;
}
}
測試結(jié)果:
public static void main(String[] args) {
JavaProxyInvocationHandler proxyHandler = new JavaProxyInvocationHandler(new Hello());
HelloService helloService = (HelloService) proxyHandler.newProxyInstance();
helloService.sayHello();
}
obj invoked before...
hi, this is Hello-Original.
obj invoked after...
CGLib 動態(tài)代理 底層將方法全部存入一個數(shù)組中,通過數(shù)組索引直接進行方法調(diào)用
方法調(diào)用
:通過字節(jié)碼文件生成委托類的子類,對非 final 委托方法
生成兩個方法:委托方法簽名相同的方法
,它在方法中會通過super調(diào)用委托方法片迅;代理類獨有的方法
腮鞍,它會判斷是否存在實現(xiàn)了MethodInterceptor接口的對象,若存在則將調(diào)用intercept方法對委托方法進行代理害驹。
public class HelloMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("HelloMethodInterceptor: before...");
Object object = methodProxy.invokeSuper(o, objects);
System.out.println("HelloMethodInterceptor: after...");
return object;
}
}
測試結(jié)果:
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Hello.class);
enhancer.setCallback(new HelloMethodInterceptor());
Hello hello = (Hello) enhancer.create();
hello.sayHello();
}
HelloMethodInterceptor: before...
hi, this is Hello-Original.
HelloMethodInterceptor: after...
CGLib 細節(jié)可以參考 深入理解CGLIB動態(tài)代理機制0 寫的挺不錯的