? ?上篇咱們介紹了容器和AOP的結合,結合后怎樣將對象增強服務并沒有過多的說明,這里將詳細說明怎樣將對象 進行增強 ,達到一個一對多和多對多的增強方式
先從簡單的方式說起
/**
*JDK代理類,實現動態調用對象方法
*/
public class JDKDynamicProxy implements InvocationHandler { /***……省略方法*//***回調使用方法,運行選擇的方法*/ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object result = method.invoke(target, args); after(); return result; } private void before() { System.out.println("Before"); } private void after() { System.out.println("After"); } }
以上代碼轉為圖形為
?
我們將詳細的顆粒固定在 了AOP中。這樣一來,若再想添加服務顆粒可得修改代碼,這不是一種非常好的解決方案。為了更好更好的將服務與AOP解耦,我們將服務咱們裝載到了一個服務容器中。
這樣就有了先前的版本號
?
?
基本是我們須要的。通過截取業務顆粒。將服務顆粒,關系集合一起傳遞到AOP中,AOP進行解析。若是有多個服務顆粒呢,于是我們有了變更版本號
將右側的服務顆粒放在了一個容器中,多個服務顆粒同一時候為一個業務對象服務。
若有多個服務顆粒,想要這寫服務同一時候為全部業務顆粒提供支持,就成了例如以下圖了
?
?1 首先通過構造函數將所須要的參數傳遞進來
private Map<String, Object> aspectBeans; // 服務容器private Map<String, Object> businessBeans;// 業務容器private Map<String, Object> relationBeans;// 關系容器/**** * @param target* 被代理對象* @param aspectBeans* 切容器* @param businessBeans* 業務容器* @param relationBeans* 關系集合*/public JDKDynamicProxy(Object target, Map<String, Object> aspectBeans,Map<String, Object> businessBeans, Map<String, Object> relationBeans) {this.target = target;this.aspectBeans = aspectBeans;this.businessBeans = businessBeans;this.relationBeans = relationBeans;}
2 ?在回調函數中 調用解析關系xml方法。進行方法調用
?
// 回調注冊切入對象方法@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {List beforeList = (List) relationBeans.get("aspectbefore");// 獲取關系容器中的關系invokeAspectName(beforeList, method, args);// 調用切面類中匹配方法Object result = method.invoke(target, args);// 調用 被代理類本身方法return result;}/*** * @Title: getAllMethod * @Description: 運行某個服務類中的全部方法,* @param @param clazz 服務類* @param @param aspectClass aop關系集合中設定運行 攔截的方法* @param @param args 被攔截對象的參數* @return void 返回類型 * @throws*/public void getAllMethod(Class clazz, String aspectClass, Object[] args)throws IllegalAccessException, IllegalArgumentException,InvocationTargetException, NoSuchMethodException, SecurityException {// 獲取服務類中的全部公共方法Method[] methods = clazz.getDeclaredMethods();for (int j = 0; j < methods.length; j++) {// 反射獲取服務類中每一個方法名稱,獲取該服務類方法Method jinectmethod = clazz.getMethod(methods[j].getName(), Object.class);// 反射調用服務類中方法jinectmethod.invoke(aspectBeans.get(aspectClass),args == null ? new Object[1] : args);}}
?
?小結:
? 以上就是對AOP關系的基本解釋,一步步逐漸演變,也不是一蹴而就的。所以回到學習上,也不是一次學習就能夠全然的,要不斷重復的思考和總結。詳細的源代碼點擊連接