6 代理模式
module:spring-08-proxy
為什么要學習代理模式,因為AOP的底層機制就是動態代理!
代理模式:
- 靜態代理
- 動態代理

靜態代理
靜態代理角色分析
- 抽象角色 : 一般使用介面或者抽象類來實作,
- 真實角色 : 被代理的角色,
- 代理角色 : 代理真實角色 ; 代理真實角色后 , 一般會做一些附屬的操作,
- 客戶 : 使用代理角色來進行一些操作,
代碼實作
Rent.java 抽象角色
package com.zzb.demo1;
public interface Rent {
public void rent();
}
Host.java 真實角色
package com.zzb.demo1;
// 真實角色,房東
public class Host implements Rent{
public void rent() {
System.out.println("房東要出租房子!");
}
}
Proxy.java 代理角色
package com.zzb.demo1;
// 代理角色,中介
public class Proxy implements Rent{
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent() {
seeHouse();
host.rent();
paper();
fare();
}
// 中介帶你看房
public void seeHouse(){
System.out.println("中介帶你看房");
}
// 簽合同
public void paper(){
System.out.println("中介帶你簽合同");
}
// 收房租
public void fare(){
System.out.println("中介收房租");
}
}
Client.java 客戶
package com.zzb.demo1;
//客戶類,一般客戶都會去找代理!
public class Client {
public static void main(String[] args) {
//房東要租房
Host host = new Host();
//中介幫助房東
Proxy proxy = new Proxy(host);
//你去找中介!
proxy.rent();
}
}
分析:在上述代碼程序中,客戶直接接觸到的是中介,就如同現實生活中的樣子,客戶見不到房東,但客戶依舊可以通過中介租到房東的房子,這就是所謂的代理模式,程式源自于生活,所以學編程的人,應該更加抽象的看待生活中的事情,
靜態代理的優點:
- 可以使得我們的真實角色更加純粹,不再去關注一些公共的事情;
- 公共的業務由代理來完成,實作了業務的分工 ;
- 公共業務發生擴展時變得更加集中和方便 ,
缺點:
- 類增多,多了代理類,作業量變大,開發效率降低
我們想要靜態代理的好處,又不想要靜態代理的缺點,所以 , 就有了動態代理 !
靜態代理再理解
1、創建一個抽象角色,業務為增刪改查
package com.zzb.demo2;
public interface UserService {
void add();
void query();
void update();
void delete();
}
2、創建一個真實物件,實作抽象介面
package com.zzb.demo2;
public class UserServiceImpl implements UserService{
public void add() {
System.out.println("add");
}
public void query() {
System.out.println("query");
}
public void update() {
System.out.println("update");
}
public void delete() {
System.out.println("delete");
}
}
3、現在來了新需求,需要實作一個日志功能:
- 思路1:在原實作類上增加日志功能代碼!【麻煩】
- 思路2:使用代理來做,能夠在不改變原代碼的情況下,實作此功能!
4、設定一個代理類來處理日志功能!代理角色
package com.zzb.demo2;
public class UserServiceProxy implements UserService{
private UserService userServiceImpl;
public void setUserServiceImpl(UserService userServiceImpl) {
this.userServiceImpl = userServiceImpl;
}
public void add() {
log("add");
userServiceImpl.add();
}
public void query() {
log("query");
userServiceImpl.query();
}
public void update() {
log("update");
userServiceImpl.update();
}
public void delete() {
log("delete");
userServiceImpl.delete();
}
// 輸出日志
public void log(String msg){
System.out.println("使用" + msg + "方法");
}
}
5、測驗
@Test
public void test(){
// 真實業務
UserServiceImpl userService = new UserServiceImpl();
// 代理類
UserServiceProxy proxy = new UserServiceProxy();
proxy.setUserServiceImpl(userService);
proxy.add();
}
測驗結果:
使用add方法
add
我們在不改變原來的代碼的情況下,實作了對原有功能的增強,這是AOP中最核心的思想,
縱向開發與橫向開發:


動態代理
- 動態代理的角色和靜態代理的一樣;
- 動態代理的代理類是動態生成的,靜態代理的代理類是我們提前寫好的;
- 動態代理分為兩類 : 一類是基于介面動態代理,一類是基于類的動態代理;
- 基于介面的動態代理——JDK動態代理;
- 基于類的動態代理--cglib;
- 現在用的比較多的是 javasist 來生成動態代理 . 百度一下javasist;
- 我們這里使用JDK的原生代碼來實作,其余的道理都是一樣的!
JDK的動態代理需要了解兩個類
核心 : InvocationHandler 呼叫處理程式 和 Proxy 代理

InvocationHandler介面

Proxy類



代碼實作:
1、Rent.java 抽象角色
package com.zzb.demo3;
public interface Rent {
public void rent();
public void goOut();
}
2、Host.java 真實角色,房東
package com.zzb.demo3;
public class Host implements Rent{
public void rent() {
System.out.println("房東出租房子");
}
public void goOut() {
System.out.println("房東來了,快跑!");
}
}
3、ProxyInvocationHandler. java 生成代理角色以及方法處理程式
package com.zzb.demo3;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
//代理介面
Object target;
public void setTarget(Object target) {
this.target = target;
}
// 生成代理類
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
//代理實列的關聯呼叫程式
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
Object result = method.invoke(target, args);
fare();
return result;
}
public void seeHouse(){
System.out.println("中介帶你看房子");
}
public void fare(){
System.out.println("中介來收中介費!");
}
}
4、測驗,client
package com.zzb.demo3;
public class Client {
public static void main(String[] args) {
Rent host = new Host();
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setTarget(host);
// 生成代理實體
Rent proxy = (Rent) pih.getProxy();
// 呼叫代理實體處理應用程式
proxy.rent();
System.out.println("=============================");
proxy.goOut();
}
}
測驗結果:
中介帶你看房子
房東出租房子
中介來收中介費!
=============================
中介帶你看房子
房東來了,快跑!
中介來收中介費!
核心:一個動態代理 , 一般代理某一類業務 , 一個動態代理可以代理多個類,代理的是介面!
**動態代理的優點
靜態代理有的它都有,靜態代理沒有的,它也有!
- 可以使得我們的真實角色更加純粹 . 不再去關注一些公共的事情;
- 公共的業務由代理來完成 . 實作了業務的分工;
- 公共業務發生擴展時變得更加集中和方便;
- 一個動態代理 , 一般代理某一類業務;
- 一個動態代理可以代理多個類,代理的是介面!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/232852.html
標籤:Java
上一篇:5 使用注解開發
下一篇:7 AOP
