在項(xiàng)目運(yùn)行的時(shí)候才創(chuàng)建一個(gè)代理對(duì)象,對(duì)方法進(jìn)行增強(qiáng)(控制)
方式1:
jdk中Proxy類,前提:實(shí)現(xiàn)接口
方式2:
spring中cglib,前提:繼承類
動(dòng)態(tài)的在內(nèi)存中創(chuàng)建一個(gè)代理對(duì)象
Object Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
參數(shù)說(shuō)明:
ClassLoader:代理對(duì)象類加載器 一般我們使用的是被代理對(duì)象的類加載器
Class[]:代理對(duì)象需要實(shí)現(xiàn)接口 一般我們使用的是被搭理對(duì)象所實(shí)現(xiàn)的所有接口
InvocationHandler:執(zhí)行處理類.在這里面對(duì)方法進(jìn)行加強(qiáng)
invocationHandler中只有一個(gè)方法:
Object invoke(Object proxy, Method method, Object[] args)
參數(shù)說(shuō)明:
proxy:代理對(duì)象
method:當(dāng)前執(zhí)行的方法
args:當(dāng)前方法執(zhí)行的時(shí)候所需要的參數(shù)
返回值:就是當(dāng)前method對(duì)象執(zhí)行的返回值
例子:QQ類繼承Car接口,實(shí)現(xiàn)了run方法和stop方法
public class TT {
public static void main(String[] args) {
final QQ qq=new QQ();
//創(chuàng)建代理對(duì)象
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í)行一次就代表原來(lái)的方法執(zhí)行了一次
Object obj = method.invoke(qq, args);
System.out.println("5秒破百");
//這里的obj表示方法的返回值,汽車的run方法是打印輸出語(yǔ)句,沒(méi)有返回值,所以obj相當(dāng)于null。
return obj;
}
//method.invoke執(zhí)行一次就代表原來(lái)的方法執(zhí)行了一次,并且通過(guò)return把這個(gè)方法的返回值返回。
return method.invoke(qq, args);
}
});
qqProxy.run();
qqProxy.stop();
}
}