靜態代理和動態代理
介紹
在一些情況下,客戶端不想或者不能夠直接引用一個對象,而代理對象就可以在客戶端和目標對象之間起到中介的作用.
代理設計模式:可以先簡單理解爲代理商或中介的概念,比如上網我們可能就會使用代理服務器去上網.
典型的代理設計模式:proxy對象不是真正的服務提供者,它只是負責中間一些驗證監控或日誌之類的操作.
備註:代理模式分爲兩種靜態代理和動態代理
抽象主題角色:聲明瞭真實主題和代理主題的共同接口
代理主題(Proxy):代理主題角色內部含有對真實主題的引用,從而在任何時候可以操作真實主題對象
真實主題:定義了代理角色所代表的真實對象
靜態代理
Net上網Subject
/**
*
* @author xuyi3
* @2016年9月13日 @上午9:35:31
* @Net 上網類(上網Subject)
* @功能說明:<br>
* @春風十里不如你
* @備註
*/
public class Net
{
/**
* 上網方法
*/
public void internet()
{
System.out.println("internet ... ");
}
}
Net上網代理對象
/**
*
* @author xuyi3
* @2016年9月13日 @上午9:31:17
* @NetProxy
* @功能說明:<br>
* @春風十里不如你
* @備註
*/
public class NetProxy
{
//Net引用
private Net net;
public NetProxy()
{
}
/**
* <h3>上網方法</h3>
* @param username
* @param password
*/
public void internet(String username, String password)
{
//首先進行身份驗證
boolean verifySuccess = verifyIdentity(username, password);
if (verifySuccess)
{
if (net == null)
{
net = new Net();
}
net.internet();
}
//上完網之後統計流量信息
countInternetTraffic();
}
/**
* <h3>驗證上網者身份</h3>
* @param username 用戶賬號
* @param password 用戶密碼
* @return
*/
private boolean verifyIdentity(String username, String password)
{
System.out.println("====身份驗證====");
//驗證上網者身份
return true;
}
/**
* <h3>統計上網信息</h3>
* @return
*/
private int countInternetTraffic()
{
System.out.println("====統計流量====");
//計算上網流量
return 0;
}
}
NetApp
/**
* @author xuyi3
* @2016年9月13日 @上午9:32:43
* @NetApp
* @功能說明:<br>
* @春風十里不如你
* @備註
*/
public class NetApp
{
public static void main(String[] args)
{
//初始化上網代理對象
NetProxy netProxy = new NetProxy();
netProxy.internet("admin", "123");
}
}
動態代理
舉例:數據庫事務操作時,每次操作都要先開啓事務然後再提交事務,這樣模板式的代碼頻繁的出現,既不安全也繁瑣.
可以使用動態代理來幫助我們處理這些樣式代碼,即AOP面向切面編程。
應用
UserService
/**
*
* @author xuyi3
* @2016年9月13日 @上午10:27:21
* @UserService
* @功能說明:<br>
* @春風十里不如你
* @備註
*/
public interface UserService
{
void addUser(String username);
}
UserServiceImpl
/**
*
* @author xuyi3
* @2016年9月13日 @上午10:25:27
* @UserServiceImpl
* @功能說明:
* @春風十里不如你
* @備註
*/
public class UserServiceImpl implements UserService
{
public void addUser(String username)
{
System.out.println("addUser ... username:" + username);
}
}
PersonService
/**
*
* @author xuyi3
* @2016年9月13日 @上午10:27:54
* @PersonService
* @功能說明:<br>
* @春風十里不如你
* @備註
*/
public interface PersonService
{
void addPerson(String name);
}
PersonServiceImpl
/**
*
* @author xuyi3
* @2016年9月13日 @上午10:25:13
* @PersonServiceImpl
* @功能說明:<br>
* @春風十里不如你
* @備註
*/
public class PersonServiceImpl implements PersonService
{
public void addPerson(String name)
{
System.out.println("addPerson... name:" + name);
}
}
ObjectProxy
/**
* 看其名字ObjectProxy就可以知道其是萬能代理對象
* @author xuyi3
* @2016年9月13日 @上午10:28:30
* @ObjectProxy
* @功能說明:<br>
* @春風十里不如你
* @備註
*/
public class ObjectProxy implements InvocationHandler
{
//待代理對象
private Object target;
/**
* <h3>通過構造方法傳入需要使用的主題實現類對象</h3>
*
* @param target
*/
public ObjectProxy(Object target)
{
this.target = target;
}
/**
* <h3>使用Proxy創建代理對象實例</h3>
* 核心方法
* @return
*/
public Object createProxy()
{
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
beforeInvoke();
// System.out.println(method.getName());// 輸出執行方法名
Object result = method.invoke(target, args);
afterInvoke();
return result;
}
private void beforeInvoke()
{
System.out.println("begin事務 ...");
}
private void afterInvoke()
{
System.out.println("commit事務 ...");
}
}
MainApp
/**
*
* @author xuyi3
* @2016年9月13日 @上午9:53:40
* @MainApp
* @功能說明:<br>
* @春風十里不如你
* @備註
*/
public class MainApp
{
public static void main(String[] args) throws Exception
{
UserService userService = new UserServiceImpl();
ObjectProxy objectProxy1 = new ObjectProxy(userService);
UserService userServiceProxy = (UserService) objectProxy1.createProxy();
userServiceProxy.addUser("admin");
System.out.println("------------------");
PersonService personService = new PersonServiceImpl();
ObjectProxy objectProxy2 = new ObjectProxy(personService);
PersonService personServiceProxy = (PersonService) objectProxy2.createProxy();
personServiceProxy.addPerson("xuyi");
}
}
總結
代理設計模式是現實開發中比較常使用到的,同時動態代理也是Spring AOP面向切面技術的基礎理論。