我們知道Spring主要有兩大思想苞氮,一個是IoC,另一個就是AOP瓤逼,對于IoC笼吟,依賴注入就不用多說了,而AOP的原理就是java的動態(tài)代理機(jī)制
在java的動態(tài)代理機(jī)制中抛姑,有兩個重要的類或接口,一個是InvocationHandler(Interface)艳狐、另一個則是 Proxy(Class)
實(shí)例:在現(xiàn)在常見的系統(tǒng)中定硝,登錄和退出是用戶必備的操作之一毫目,下面我就設(shè)計(jì)這么一個接口蔬啡,用于處理用戶的登錄和退出操作
public interface User {
/**
* 登錄
* @param name 用戶名
* @param pwd 密碼
* @return
*/
public boolean login(String username, String pwd);
/**
* 退出
*/
public void logout(String username);
}```
委托類:
public class UserImpl implements User{
@Override
public boolean login(String username, String pwd) {
// 簡化問題,直接登錄成功
System.out.println(username+" 登錄成功.");
return true;
}
@Override
public void logout(String username) {
System.out.println(username+" 成功退出.");
}
}```
代理類:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 繼承動態(tài)代理接口的代理類
*/
public class UserDynamicProxy implements InvocationHandler{
// 在線人數(shù)
public static int count = 0;
// 委托對象
private Object target;
/**
* 返回代理對象
* @param target
* @return
*/
@SuppressWarnings("unchecked")
public <T> T getProxyInstance(Object target) {
// 委托對象镀虐,真正的業(yè)務(wù)對象
this.target = target;
// 獲取Object類的ClassLoader
ClassLoader cl = target.getClass().getClassLoader();
// 獲取接口數(shù)組
Class<?>[] cs = target.getClass().getInterfaces();
// 獲取代理對象并返回
return (T)Proxy.newProxyInstance(cl, cs, this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object r = null;
// 執(zhí)行之前
r = method.invoke(target, args);
// 判斷如果是登錄方法
if("login".equals(method.getName())) {
if((boolean)r == true) {
// 當(dāng)前在線人數(shù)+1
count += 1;
}
}
// 判斷如果是退出方法
else if("logout".equals(method.getName())) {
// 當(dāng)前在線人數(shù)-1
count -= 1;
}
showCount(); // 輸出在線人數(shù)
// 執(zhí)行之后
return r;
}
/**
* 輸出在線人數(shù)
*/
public void showCount() {
System.out.println("當(dāng)前在線人數(shù):"+count+" 人.");
}
}```
測試類:
public class Main {
public static void main(String[] args) {
// 真實(shí)角色箱蟆,委托人
User user = new UserImpl(); // 可執(zhí)行真正的登錄退出功能
// 代理類
UserDynamicProxy proxy = new UserDynamicProxy();
// 獲取委托對象user的代理對象
User userProxy = proxy.getProxyInstance(user);
// 系統(tǒng)運(yùn)行,用戶開始登錄退出
userProxy.login("小明", "111");
userProxy.login("小紅", "111");
userProxy.login("小剛", "111");
userProxy.logout("小明");
userProxy.logout("小剛");
userProxy.login("小黃", "111");
userProxy.login("小黑", "111");
userProxy.logout("小黃");
userProxy.login("小李", "111");
userProxy.logout("小李");
userProxy.logout("小黃");
userProxy.logout("小紅");
}
}```
輸出結(jié)果如下:
小明 登錄成功.
當(dāng)前在線人數(shù):1 人.
小紅 登錄成功.
當(dāng)前在線人數(shù):2 人.
小剛 登錄成功.
當(dāng)前在線人數(shù):3 人.
小明 成功退出.
當(dāng)前在線人數(shù):2 人.
小剛 成功退出.
當(dāng)前在線人數(shù):1 人.
小黃 登錄成功.
當(dāng)前在線人數(shù):2 人.
小黑 登錄成功.
當(dāng)前在線人數(shù):3 人.
小黃 成功退出.
當(dāng)前在線人數(shù):2 人.
小李 登錄成功.
當(dāng)前在線人數(shù):3 人.
小李 成功退出.
當(dāng)前在線人數(shù):2 人.
小黃 成功退出.
當(dāng)前在線人數(shù):1 人.
小紅 成功退出.
當(dāng)前在線人數(shù):0 人.```