在項目運行的時候才創(chuàng)建一個代理對象,對方法進行增強(控制)
方式1:
jdk中Proxy類,前提:實現(xiàn)接口
方式2:
spring中cglib,前提:繼承類
動態(tài)的在內(nèi)存中創(chuàng)建一個代理對象
Object Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
參數(shù)說明:
ClassLoader:代理對象類加載器 一般我們使用的是被代理對象的類加載器
Class[]:代理對象需要實現(xiàn)接口 一般我們使用的是被搭理對象所實現(xiàn)的所有接口
InvocationHandler:執(zhí)行處理類.在這里面對方法進行加強
invocationHandler中只有一個方法:
Object invoke(Object proxy, Method method, Object[] args)
參數(shù)說明:
proxy:代理對象
method:當前執(zhí)行的方法
args:當前方法執(zhí)行的時候所需要的參數(shù)
返回值:就是當前method對象執(zhí)行的返回值
例子:QQ類繼承Car接口碳蛋,實現(xiàn)了run方法和stop方法
public class TT {
public static void main(String[] args) {
final QQ qq=new QQ();
//創(chuàng)建代理對象
Car qqProxy=(Car) Proxy.newProxyInstance(QQ.class.getClassLoader(), new Class[]{Car.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("run".equals(method.getName())){
System.out.println("加上電池");
//這里的obj表示方法的返回值,method.invoke執(zhí)行一次就代表原來的方法執(zhí)行了一次
Object obj = method.invoke(qq, args);
System.out.println("5秒破百");
//這里的obj表示方法的返回值眶掌,汽車的run方法是打印輸出語句作煌,沒有返回值酝蜒,所以obj相當于null吕粹。
return obj;
}
//method.invoke執(zhí)行一次就代表原來的方法執(zhí)行了一次,并且通過return把這個方法的返回值返回疼进。
return method.invoke(qq, args);
}
});
qqProxy.run();
qqProxy.stop();
}
}