設(shè)計模式—結(jié)構(gòu)型模式之代理模式
代理模式(Proxy Pattern) ,給某一個對象提供一個代理,并由代理對象控制對原對象的引用,對象結(jié)構(gòu)型模式。
靜態(tài)代理
比如我們有一個直播平臺,提供了直播功能,但是如果不進(jìn)行美顏,可能就比較冷清。所以美顏功能就是我們的增強(qiáng),可以用靜態(tài)代理來實(shí)現(xiàn)。
直播接口:
/**
* 直播接口
*/
public interface LiveBroadCastInterface {
void liveBroadcast();
}
直播類:
/**
* 實(shí)現(xiàn)直播接口
*/
public class SjdwzLiveBroadCast implements LiveBroadCastInterface{
@Override
public void liveBroadcast() {
System.out.println("我來直播了......");
}
}
如果沒有美顏,可能就會比較冷清;所以我們可以提供一個靜態(tài)代理,來為我們的直播進(jìn)行增強(qiáng)。
要代理的功能類要和原類型實(shí)現(xiàn)相同的接口。
public class SjdwzStaticProxy implements LiveBroadCastInterface{
private LiveBroadCastInterface liveBroadCastInterface;
public SjdwzStaticProxy(LiveBroadCastInterface liveBroadCastInterface) {
this.liveBroadCastInterface = liveBroadCastInterface;
}
@Override
public void liveBroadcast() {
System.out.println("這是代理的功能");
System.out.println("美顏--------");
System.out.println("=========原功能如下=========");
this.liveBroadCastInterface.liveBroadcast();
}
}
測試類如下:
public class StaticSjdwzProxyTest {
public static void main(String[] args) {
SjdwzStaticProxy sjdwzStaticProxy = new SjdwzStaticProxy(new SjdwzLiveBroadCast());
sjdwzStaticProxy.liveBroadcast();
}
}
運(yùn)行如下:
jdk動態(tài)代理
還是上面的例子,可以使用JDK的動態(tài)代理來實(shí)現(xiàn):
/**
* 實(shí)現(xiàn)InvocationHandler的作用是為了在本類實(shí)現(xiàn)增強(qiáng)方法,
* @param <T> 要代理對象實(shí)現(xiàn)的接口
*/
public class JdkLiveBroadCastProxy<T> implements InvocationHandler {
//被代理對象
private T target;
public JdkLiveBroadCastProxy(T target) {
this.target = target;
}
public static<T> T getProxy(T t){
/**
* ClassLoader loader, 當(dāng)前被代理對象的類加載器
* Class<?>[] interfaces, 當(dāng)前被代理對象所實(shí)現(xiàn)的所有接口
* InvocationHandler h,
* 當(dāng)前被代理對象執(zhí)行目標(biāo)方法的時候我們使用h可以定義攔截增強(qiáng)方法
*/
Object o = Proxy.newProxyInstance(
t.getClass().getClassLoader(),
t.getClass().getInterfaces(), //必須接口
new JdkLiveBroadCastProxy(t));
return (T)o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("這是代理的一些功能======");
System.out.println("原本的功能===========");
//反射執(zhí)行
Object invoke = method.invoke(this.target, args);
System.out.println("返回值:"+invoke);
return invoke;
}
}
測試類如下:
public class JdkLiveBroadCastProxyTest {
public static void main(String[] args) {
LiveBroadCastInterface proxy = JdkLiveBroadCastProxy.getProxy(new SjdwzLiveBroadCast());
proxy.liveBroadcast();
}
}
運(yùn)行結(jié)果如下:
要求
JDK要求被代理對象必須有接口,因?yàn)楸仨氂薪涌诓拍芨嬖V代理有哪些方法。
cglib動態(tài)代理
我們發(fā)現(xiàn),如果使用JDK的動態(tài)代理,必須實(shí)現(xiàn)接口。cglib動態(tài)代理是不需要實(shí)現(xiàn)接口的。
首先我們在項目的pom文件中引入依賴:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
cglib動態(tài)代理類如下:
public class CglibProxy {
//為任意對象創(chuàng)建代理
public static<T> T createProxy(T t){
//1、創(chuàng)建一個增強(qiáng)器
Enhancer enhancer = new Enhancer();
//2、設(shè)置要增強(qiáng)哪個個類的功能。增強(qiáng)器為這個類動態(tài)創(chuàng)建一個子類
enhancer.setSuperclass(t.getClass());
//3、設(shè)置回調(diào)
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj,
Method method, //為了能獲取到原方法的一些元數(shù)據(jù)信息
Object[] args,
MethodProxy proxy) throws Throwable {
//編寫增強(qiáng)的邏輯
System.out.println("cglib的動態(tài)代理增強(qiáng)的功能===========");
System.out.println("原功能===========");
//目標(biāo)方法進(jìn)行執(zhí)行
Object invoke = proxy.invokeSuper(obj,args);
return invoke;
}
});
Object o = enhancer.create();
return (T) o;
}
}
測試類如下:文章來源:http://www.zghlxwxcb.cn/news/detail-746146.html
public class MyCglibProxyTest {
public static void main(String[] args) {
SjdwzLiveBroadCast proxy = CglibProxy.createProxy(new SjdwzLiveBroadCast());
proxy.liveBroadcast();
}
}
運(yùn)行截圖如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-746146.html
到了這里,關(guān)于設(shè)計模式—結(jié)構(gòu)型模式之代理模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!