1. 程式人生 > 其它 >設計模式---代理模式

設計模式---代理模式

常用代理模式的基本介紹

代理模式:為一個物件提供一個替身,以控制對這個物件的訪問。即通過代理物件訪問目標物件.這樣做的好處是:可以在目標物件實現的基礎上,增強額外的功能操作,即擴充套件目標物件的功能。

靜態代理

介紹:靜態代理在使用時,需要定義介面或者父類,被代理物件(即目標物件)與代理物件一起實現相同的介面或者是繼承相同父類

程式碼:

package com.study.designPattern;

/**
* @Author guangwenyin
*
*/
public class StaticProxyTest {
public static void main(String[] args) {
//建立目標物件
TargetClass targetClass=new TargetClass();
//建立代理物件
ProxyClass proxyClass=new ProxyClass(targetClass);
//執行代理物件的方法
proxyClass.m1();
}
}

//目標類實現的介面
interface ITest{

void m1();
}

//目標類
class TargetClass implements ITest{

@Override
public void m1() {
System.out.println("i am TargetClass m1()...");
}
}

//代理類
class ProxyClass implements ITest{

TargetClass targetClass;

public ProxyClass(TargetClass targetClass) {
this.targetClass = targetClass;
}

@Override
public void m1() {
System.out.println("i am ProxyClass m1 start...");
targetClass.m1();
System.out.println("i am ProxyClass m1 end...");
}
}

動態代理

JDK動態代理

介紹:代理物件,不需要實現介面,但是目標物件要實現介面,否則不能用jdk動態代理

程式碼:

package com.study.designPattern;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
* @Author guangwenyin
*
*/
public class JDKDynamicProxyTest {
public static void main(String[] args) {
//建立目標物件
TargetClass2 targetClass2=new TargetClass2();
//建立代理物件
ITest2 iTest2 = (ITest2) Proxy.newProxyInstance(ITest2.class.getClassLoader(),
TargetClass2.class.getInterfaces(),
(proxy, method, args1) -> {
System.out.println("i am jdk proxy start ...");
Object result = method.invoke(targetClass2, args1);
System.out.println("i am jdk proxy end ...");
return result.toString()+" how are you?";
});
//呼叫代理物件方法,並獲取返回值
String s = iTest2.m2();
System.out.println(s);

}
}

//目標類實現的介面
interface ITest2{
String m2();
}

//目標類
class TargetClass2 implements ITest2{

@Override
public String m2() {
System.out.println("i am TargetClass2 m2()...");
return "hello jdk proxy!";
}
}


Cglib動態代理

介紹:靜態代理和 JDK 代理模式都要求目標物件是實現一個介面,但是有時候目標物件只是一個單獨的物件,並沒有實現任何的介面,這個時候可使用目標物件子類來實現代理-這就是 Cglib 代理,用cglib要先引用相關依賴。

程式碼:

package com.study.designPattern;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
* @Author guangwenyin
*
*/
public class CglibProxyTest {
public static void main(String[] args) {
//建立目標物件
TargetClass3 targetClass3=new TargetClass3();
//建立代理工廠物件
CglibProxyFactory cglibProxyFactory=new CglibProxyFactory(targetClass3);
//建立代理物件
TargetClass3 proxyInstance = (TargetClass3) cglibProxyFactory.getProxyInstance();
//呼叫代理物件方法
String s = proxyInstance.m3();
System.out.println(s);
}
}

//目標類
class TargetClass3{
String m3(){
System.out.println("i am TargetClass3 m3()...");
return "hello cglib proxy!";
}
}

//代理工廠
class CglibProxyFactory implements MethodInterceptor {

Object target;

public CglibProxyFactory(Object target) {
this.target = target;
}

public Object getProxyInstance(){
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}


@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("i am cglib proxy start...");
Object result = method.invoke(target, objects);
System.out.println("i am cglib proxy end...");
return result+" how are you?";
}
}