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

歡迎訪問 生活随笔!

生活随笔

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

javascript

08 Spring框架 AOP (一)

發布時間:2023/12/1 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 08 Spring框架 AOP (一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先我們先來介紹一下AOP:?

  AOP(Aspect Orient Programming),面向切面編程,是面向對象編程OOP的一種補充。

  面向對象編程是從靜態角度考慮程序的結構,面向切面編程是從動態的角度考慮程序運行過程。

  AOP底層,就是采用動態代理模式實現的。采用兩種代理:JDK的動態代理,與CGLIB的動態代理。

  JDK的動態代理是面向接口的,CGLIB既可以實現有接口的,又可以實現沒有接口的。(對動態代理不了解的可以看看我的其關于動態代理的介紹)

  面向切面編程,就是將交叉業務邏輯封裝成切面,利用AOP容器的功能將切面植入到主業務邏輯中。所謂交叉業務邏輯是指:通用的,與主業務邏輯無關的代碼,如安全檢查,事務日志等。

Spring的AOP的幾種用法:

通知:即我們的切面方法

  • 前置通知
  • 后置通知
  • 環繞通知
  • 異常通知

  • (一)前置通知?
      所謂前置通知,就是這個切面方法在我們的主業務方法之前執行。

    首先我們先寫一個目標接口:

    //目標接口 public interface SomeServices {String doFirst();void doSecond(); } //接口實現類,也就是主業務方法類 public class SomeServiceImp implements SomeServices{@Overridepublic String doFirst() {System.out.println("print first");return null;}@Overridepublic void doSecond() {System.out.println("print second");} } //切面方法,需要實現:**MethodBeforeAdvice** 接口 public class myBeforeMethodAdvice implements MethodBeforeAdvice {//method:業務方法//args:方法參數//target:目標類 @Overridepublic void before(Method method, Object[] arg1, Object target) throws Throwable {System.out.println("執行主業務前方法");}} <!--Spring主配置文件--><bean id="service" class="com.test.beforeMethodAdvice.SomeServiceImp"/><bean id="myAdvice" class="com.test.beforeMethodAdvice.myBeforeMethodAdvice"/><bean id="ProxyService" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="target" ref="service"/><!--<property name="target" value="service"/>--><property name="interceptorNames" value="myAdvice"/></bean>

    接著是測試方法:

    public class test {@Testpublic void Test01() {String source = "com/test/beforeMethodAdvice/applicationContext.xml";ApplicationContext ac = new ClassPathXmlApplicationContext(source);SomeServices service = (SomeServices)ac.getBean("ProxyService");service.doFirst();service.doSecond();} } //控制臺輸出: //執行主業務前方法 //print first //執行主業務前方法 //print second

    (二)后置通知?

      后置通知和前置通知雷同,只是切面方法的實現類不同,但是后置通知實現接口方法,多給用了一個returnValue參數,也就意味著我們可以獲得主業務方法的返回值,我們來看看范例:

    //主業務接口 public interface SomeServices {String doFirst();void doSecond(); } //主業務方法實現類,doFirst()有返回值 package com.test.afterMethodAdvice;public class SomeServiceImp implements SomeServices{@Overridepublic String doFirst() {System.out.println("print first");return "abc";}@Overridepublic void doSecond() {System.out.println("print second");} } //實現了**AfterReturningAdvice** 接口,實現這個接口的方法有一個返回值參數 public class myAfterMethodAdvice implements AfterReturningAdvice {//returnValue:業務方法的返回值//method:業務方法屬性類//args:方法參數//target:目標類 @Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println("執行業務后方法");//只能獲取到業務方法的返回值,但是不能進行修改 System.out.println(returnValue);} <!--配置文件沒什么差別--><bean id="service" class="com.test.afterMethodAdvice.SomeServiceImp"/><bean id="myAdvice" class="com.test.afterMethodAdvice.myAfterMethodAdvice"/><bean id="ProxyService" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="target" ref="service"/><!--<property name="targetName" value="service"/>--><property name="interceptorNames" value="myAdvice"/></bean>

    測試方法:

    public class test {@Testpublic void Test01() {String source = "com/test/afterMethodAdvice/applicationContext.xml";ApplicationContext ac = new ClassPathXmlApplicationContext(source);SomeServices service = (SomeServices)ac.getBean("ProxyService");service.doFirst();service.doSecond();} } //print first //執行業務后方法 //abc //print second //執行業務后方法 //null

    (三)環繞通知?

      環繞通知就是既能實現前置通知又能實現后置通知,但是不同的是它能夠對主業務方法進行修改。

    //主業務接口 public interface SomeServices {String doFirst();void doSecond(); } //主業務方法實現類 public class SomeServiceImp implements SomeServices{@Overridepublic String doFirst() {System.out.println("print first");return "abc";}@Overridepublic void doSecond() {System.out.println("print second");} } //環繞通知,切面方法類,需要實現**MethodInterceptor** //并且調用參數的proceed方法,這個方法有一個返回值,也就是主業務方法的返回值,我們可以對它進行修改。 public class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("環繞通知,業務方法前");Object result = invocation.proceed();System.out.println("環繞通知,業務方法后");if(result != null) {result = ((String)result).toUpperCase();}return result;} } //環繞通知的配置文件 <bean id="service" class="com.test.MethodInterceptor.SomeServiceImp"/><bean id="myAdvice" class="com.test.MethodInterceptor.MyMethodInterceptor"/><bean id="ProxyService" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="target" ref="service"/><property name="interceptorNames" value="myAdvice"/></bean> //測試方法: public class test {@Testpublic void Test01() {String source = "com/test/MethodInterceptor/applicationContext.xml";ApplicationContext ac = new ClassPathXmlApplicationContext(source);SomeServices service = (SomeServices)ac.getBean("ProxyService");String result = service.doFirst();System.out.println(result);service.doSecond();} } //控制臺輸出: //環繞通知,業務方法前 //print first //環繞通知,業務方法后 //ABC //環繞通知,業務方法前 //print second //環繞通知,業務方法后

    (四)異常通知

      異常通知就是當我們的主業務方法出現異常的時候,會對這個主業務方法進行加強!

      例如:我們現在的主業務方法是對用戶名和密碼進行判斷,如果用戶名或者密碼有誤,我們就就分別拋出對應的錯誤,當無誤的時候,程序正常執行。

    //主業務接口,判斷用戶名,密碼是否正確 public interface SomeServices {boolean checkedUser(String username,String password) throws UserException; } //實現類,實現了對用戶和密碼的校驗 public class SomeServiceImp implements SomeServices{@Overridepublic boolean checkedUser(String username, String password)throws UserException {if(!"admin".equals(username.trim())) {throw new UsernameException("用戶名錯誤");}if(!"123".equals(password.trim())){throw new PasswordException("密碼錯誤");}return true;} }

    上面兩個是我們需要的主業務方法,里面我們定義了兩個異常:UsernameException,PasswordException,它們都實現了父類UserException:

    //UserException public class UserException extends Exception {public UserException() {super();}public UserException(String message) {super(message);} } //UsernameException public class UsernameException extends UserException {public UsernameException() {super();}public UsernameException(String message) {super(message);} } //PasswordException public class PasswordException extends UserException {public PasswordException() {super();}public PasswordException(String message) {super(message);}}

    定義好上面的異常后我們就要定義我們的通知類了:

    //這個異常通知需要實現ThrowsAdvice接口,接口源碼上面有,我們追蹤到源碼會發現這個接口沒有需要實現的方法,其實是由幾個供我們選擇,防止我們沒有必要的實現全部方法public class MyThrowsAdvice implements ThrowsAdvice {public void afterThrowing(Exception ex) {System.out.println("執行異常通知方法:" + ex.getMessage());} }

    配置文件沒有什么變化:

    <bean id="service" class="com.test.afterExceptionAdvice.SomeServiceImp"/><bean id="myAdvice" class="com.test.afterExceptionAdvice.MyThrowsAdvice"/><bean id="ProxyService" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="target" ref="service"/><property name="interceptorNames" value="myAdvice"/></bean>

    最后就是我們的測試方法:

    public class test {@Testpublic void Test01() {String source = "com/test/afterExceptionAdvice/applicationContext.xml";ApplicationContext ac = new ClassPathXmlApplicationContext(source);SomeServices service = (SomeServices)ac.getBean("ProxyService");//service.checkedUser("admin", "123");//service.checkedUser("ad", "123");try {service.checkedUser("admin", "12");} catch (UserException e) {e.printStackTrace();}} } //控制臺: //**報錯** //執行異常通知方法:密碼錯誤

    本篇文章可能主要是代碼的實現,原理上沒有說的太多,因為前面關于動態代理的文章我也寫了一篇,所以這里就沒有贅述太多動態代理的知識。?

    ?

    ?

    ?

    ?

    版權聲明:本文為博主原創文章,如需轉載請表明出處。 https://blog.csdn.net/qq_39266910/article/details/78742552?

    ?

    轉載于:https://www.cnblogs.com/chengshun/p/9776849.html

    總結

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

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