日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring AOP 本质(3)

發布時間:2024/4/14 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring AOP 本质(3) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Spring AOP 本質(3) Spring AOP很牛,AOP是OOP的補充,而非競爭者。 前面的例子離實際的應用太遙遠。不足以顯式AOP的力量,現在就用AOP前置通知來檢查用戶的身份,只有通過檢查的才能調用業務方法。 在沒有使用AOP之前,我們是如何實現的?想想看。 1、寫一個安全檢查類,又其他類繼承,并在子類的業務方法中調用安全檢查的方法。 比如:Struts1時代就是繼承Action,其類結構如下: package org.apache.struts.action;

public class Action {

????public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, ServletRequest servletRequest, ServletResponse servletResponse) throws java.lang.Exception { /* compiled code */ }

????public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, http.HttpServletRequest httpServletRequest, http.HttpServletResponse httpServletResponse) throws java.lang.Exception { /* compiled code */ }

????....
}
在開發中自己實現的UserAction需要繼承Struts的Action,可以考慮做一個抽象,比如叫做CheckAciton,在其中重寫execute方法,并加入安全檢查機制,并且增加一個抽象請求處理方法
public ActionForward real(ActionMapping actionMapping, ActionForm actionForm, http.HttpServletRequest httpServletRequest, http.HttpServletResponse httpServletResponse)throws java.lang.Exception;
作為業務請求處理的方法,放到重寫的execute方法內部調用。 public class CheckAction extends Action{

????public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, http.HttpServletRequest httpServletRequest, http.HttpServletResponse httpServletResponse) throws java.lang.Exception {
????//todo: 安全檢查邏輯
????return real(actionMapping,actionForm,httpServletRequest,httpServletResponse);

????}

????public abstract ActionForward real(ActionMapping actionMapping, ActionForm actionForm, http.HttpServletRequest httpServletRequest, http.HttpServletResponse httpServletResponse) throws java.lang.Exception;

} 這樣以后業務上的別的Aciton只要繼承了CheckAction,還需要實現real方法,別的方法),即可為該Action加入安全檢查的邏輯。 public class DoSomethingAction extends CheckAction{

????public abstract ActionForward real(ActionMapping actionMapping, ActionForm actionForm, http.HttpServletRequest httpServletRequest, http.HttpServletResponse httpServletResponse) throws java.lang.Exception{
????//todo: 單純處理實際的業務請求
????return ...
????}

????....
} 這樣做也很麻煩,還可以使用動態代理為每個業務接口加上安全檢查的邏輯,但是性能更差,更麻煩。 這個還算可行的方案,實現也很容易。但是很死板,如果有多種驗證策略就比較棘手了。 沒有對比就顯式不出來Spring AOP的優勢。下面看看Spring的優雅處理: /**
* 用戶登錄信息載體
*/

public class UserInfo {
????private String userName;

????private String password;

????public UserInfo(String userName, String password) {
????????this.userName = userName;
????????this.password = password;
????}
????
????public String getPassword() {
????????return password;
????}
????public String getUserName() {
????????return userName;
????}
} /**
* 業務組件:被代理的對象
*/

public class SecureBean {

????/**
???? * 示范性的業務方法,這個方法將被攔截,加入一些附加邏輯
???? */

????public void businessOperate() {
????????System.out.println("業務方法businessOperate()被調用了!");
????}
} /**
* 安全管理類:檢查用戶登錄和管理用戶注銷登錄的業務邏輯。
*/

public class SecurityManager {
????//為每一個SecurityManager創建一個本地線程變量threadLocal,用來保存用戶登錄信息UserInfo
????private static ThreadLocal threadLocal = new ThreadLocal();

????/**
???? * 用戶登錄方法,允許任何用戶登錄。
???? * @param userName
???? * @param password
???? */

????public void login(String userName, String password) {
????????// 假定任何的用戶名和密碼都可以登錄
????????// 將用戶登錄信息封裝為UerInfo對象,保存在ThreadLocal類的對象threadLocal里面
????????threadLocal.set(new UserInfo(userName, password));
????}

????public void logout() {
????????// 設置threadLocal對象為null
????????threadLocal.set(null);
????????int x = 0;
????}

????public UserInfo getLoggedOnUser() {
????????// 從本地線程變量中獲取用戶信息UerInfo對象
????????return (UserInfo) threadLocal.get();
????}
} import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

/**
* 前置通知類
*/

public class SecurityAdvice implements MethodBeforeAdvice {

????private SecurityManager securityManager;

????public SecurityAdvice() {
????????this.securityManager = new SecurityManager();
????}

????/**
???? * 前置通知的接口方法實現。僅允許robh用戶登錄,強制設定的。
???? */

????public void before(Method method, Object[] args, Object target)
????????????throws Throwable {
????????UserInfo user = securityManager.getLoggedOnUser();

????????if (user == null) {
????????????System.out.println("沒有用戶憑證信息!,本前置通知僅僅允許robh用戶登錄,不信你試試看!");
????????????throw new SecurityException(
????????????????????"你必須在調用此方法" + method.getName() + "前進行登錄:");
????????} else if ("robh".equals(user.getUserName())) {
????????????System.out.println("用戶robh成功登錄:OK!");
????????} else {
????????????System.out.println("非法用戶"+user.getUserName()+",請使用robh登錄,用戶調用的方法是:" + method.getName());
????????????throw new SecurityException("用戶" + user.getUserName()
????????????????????+ " 不允許調用" + method.getName() + "方法!");
????????}
????}
}
? import org.springframework.aop.framework.ProxyFactory;

/**
* 測試類,客戶端
*/

public class SecurityExample {

????public static void main(String[] args) {
????????//得到一個 security manager
????????SecurityManager mgr = new SecurityManager();

????????//獲取一個SecureBean的代理對象
????????SecureBean bean = getSecureBean();

????????//嘗試用robh登錄
????????mgr.login("robh", "pwd");?? //檢查登錄情況
????????bean.businessOperate();???? //業務方法調用
????????mgr.logout();?????????????? //注銷登錄

????????//嘗試用janm登錄
????????try {
????????????mgr.login("janm", "pwd");?????? //檢查登錄情況
????????????bean.businessOperate();???????? //業務方法調用
????????} catch (SecurityException ex) {
????????????System.out.println("發生了異常: " + ex.getMessage());
????????} finally {
????????????mgr.logout();?????????????????? //注銷登錄
????????}

????????// 嘗試不使用任何用戶名身份調用業務方法
????????try {
????????????bean.businessOperate();???????? //業務方法調用
????????} catch (SecurityException ex) {
????????????System.out.println("發生了異常: " + ex.getMessage());
????????}

????}

????/**
???? * 獲取SecureBean的代理對象
???? *
???? * @return SecureBean的代理
???? */

????private static SecureBean getSecureBean() {
????????//創建一個目標對象
????????SecureBean target = new SecureBean();

????????//創建一個通知
????????SecurityAdvice advice = new SecurityAdvice();

????????//獲取代理對象
????????ProxyFactory factory = new ProxyFactory();
????????factory.setTarget(target);
????????factory.addAdvice(advice);
????????SecureBean proxy = (SecureBean) factory.getProxy();

????????return proxy;
????}
} 運行結果: - Using JDK 1.4 collections
用戶robh成功登錄:OK!
業務方法businessOperate()被調用了!
非法用戶janm,請使用robh登錄,用戶調用的方法是:businessOperate
發生了異常: 用戶janm 不允許調用businessOperate方法!
沒有用戶憑證信息!,本前置通知僅僅允許robh用戶登錄,不信你試試看!
發生了異常: 你必須在調用此方法businessOperate前進行登錄:

Process finished with exit code 0 觀察運行結果,精確實現了驗證的要求。 這里從底層觀察Spring AOP的應用,實際應用中最好還是通過xml配置耦合代碼。只有明白了AOP其中奧秘,使用Spring的配置才能深諳其中的精妙!

總結

以上是生活随笔為你收集整理的Spring AOP 本质(3)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。