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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Spring框架-AOP核心

發布時間:2023/10/11 编程问答 142 如意码农
生活随笔 收集整理的這篇文章主要介紹了 Spring框架-AOP核心 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Spring AOP

AOP (Aspect Oriented Programming) 面向切面編程

OOP(Object Oriented Programming)面向對象編程,用對象的思想來完善程序

AOP是的OOP的一個補充,是在另外一個維度上抽象出的對象。

具體是指程序運行時動態的將非業務代碼切入到業務代碼中,從而實現程序的解耦合,將非業務抽象成一個對象,對對象編程就是面向對象編程。

在同樣的地方有相同的方法抽象成一個切面----代碼A切面對象。

AOP的優點:

  • 可以降低模塊之間的耦合性

  • 提高代碼的復用性

  • 集中管理代碼的維護性

  • 集中管理代碼的非義務代碼,便于維護

  • 業務代碼不受非業務代碼的影響,邏輯更加清晰

    理解AOP

  1. 創建接口的計算器類

    java
    package com.southwind.aop;

    public interface Cal {

    public int add(int num1,int num2);

    public int sub(int num1,int num2);

    public int mul(int num1,int num2);

    public int div(int num1,int num2);

    }

2.實現類:

package com.southwind.aop.impl;

import com.southwind.aop.Cal;

public class CalImpl implements Cal {
    @Override
    public int add(int num1, int num2) {
        int result = num1+num2;
        return result;
    }

    @Override
    public int sub(int num1, int num2) {
        int result = num1-num2;
        return result;
    }

    @Override
    public int mul(int num1, int num2) {
        int result = num1*num2;
        return result;
    }

    @Override
    public int div(int num1, int num2) {
        int result = num1/num2;
        return result;
    }
}

3.日志打印:

  • 在每個方法開始的位置輸出參數的信息

  • 在每個方法的結束的位置輸出結果信息

    對于計算器而言,加減乘除是業務代碼,日志是非業務代碼。

    AOP如何實現?:

    使用動態代理

    代理首先具備CaLImpl的基礎功能,然后在這個基礎上擴展日志功能

  1. 刪除CalImpl方法中的打印日志的代碼,只保留業務代碼

  2. 創建MyinvocationHandler類,實現IvocationHandler接口,生成動態代理類

    動態代理類要動態生成。

    ClassLoader用來將動態的類加載到虛擬機(JVM)中。

    Proxy.newProxyInstance(類加載器《object.getClass.getClassLoder》,委托對象的接口《object.getClass().getInterfaces()》,this);

    動態創建代理類---方到實體類里面。

底層原理

 1.接口:

 ```java
 package com.southwind.aop;

 public interface Cal {
     public int add(int num1,int num2);
     public int sub(int num1,int num2);
     public int mul(int num1,int num2);
     public int div(int num1,int num2);
 }

2.代理對象:

 package com.southwind.aop;

 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.Arrays;

 public class MyinvocationHandler implements InvocationHandler {
     //委托對象
     private  Object object=null;
     //返回代理對象
     public  Object bind(Object object){
         this.object=object;
         return Proxy.newProxyInstance(object.getClass().getClassLoader(),
                 object.getClass().getInterfaces(),this);
     }

?
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//實現業務代碼和非業務代碼調用
System.out.println(method.getName()+"方法的參數是:"+ Arrays.toString(args));
Object result=method.invoke(this.object,args);
System.out.println(method.getName()+"方法的參數是:"+ result);
return result;
}
}
```

 3.實現類;

 ```java
 package com.southwind.aop.impl;

 import com.southwind.aop.Cal;

 public class CalImpl implements Cal {
     @Override
     public int add(int num1, int num2) {
         int result = num1+num2;
         return result;
     }

     @Override
     public int sub(int num1, int num2) {
         int result = num1-num2;
         return result;
     }

     @Override
     public int mul(int num1, int num2) {
         int result = num1*num2;
         return result;
     }

     @Override
     public int div(int num1, int num2) {
         int result = num1/num2;
         return result;
     }
 }

4.測試類:

?     

?```java
package com.southwind.test;

import com.southwind.aop.Cal;
import com.southwind.aop.MyinvocationHandler;
import com.southwind.aop.impl.CalImpl;

public class Test10 {
    public static void main(String[] args) {
        //實例化委托對象
        Cal cal = new CalImpl();
//        cal.add(10,3);
//        cal.div(10,3);
//        cal.mul(10,3);
//        cal.sub(10,3);
//        獲取代理對象
        MyinvocationHandler myinvocationHandler= new MyinvocationHandler();
        Cal proxy=(Cal)myinvocationHandler.bind(cal);
        proxy.add(10,3);

    }
}

上述代碼的動態機制實現了業務代碼和非業務代碼的解耦合,這是SpringAOP的底層實現機制,不要這么復雜,有更好的方式。

Spring AOP的開發步驟:

1.創建切面類:

package com.southwind.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Array;
import java.util.Arrays;

@Component
@Aspect
public class LogAspect {
    @Before("execution(public  int  com.southwind.aop.impl.CalImpl.*(..))")
    public void before(JoinPoint joinPoint){
        String name=joinPoint.getSignature().getName();
        String args= Arrays.toString((joinPoint.getArgs()));
        System.out.println(name+"方法的參數是"+args);

    }
    @After("execution(public  int  com.southwind.aop.impl.CalImpl.*(..))")
    public void after(JoinPoint joinPoint){
        String name=joinPoint.getSignature().getName();
        System.out.println(name+"方法執行完畢");

    }
    @AfterReturning(value = "execution(public  int  com.southwind.aop.impl.CalImpl.*(..))",returning = "result")
    public  void afterReturn(JoinPoint joinPoint,Object result){
        String  name=joinPoint.getSignature().getName();
        System.out.println(name+"方法執行完畢"+"結果是:"+result);

    }
    @AfterThrowing(value = "execution(public  int  com.southwind.aop.impl.CalImpl.*(..))",throwing = "ex")
    public void afterTrowing(JoinPoint joinPoint,Exception ex){
        String name= joinPoint.getSignature().getName();
        System.out.println(name+"方法拋出異常"+ex);
    }

}

2.委托類加上@Component

package com.southwind.aop.impl;

import com.southwind.aop.Cal;
import org.springframework.stereotype.Component;

@Component
public class CalImpl implements Cal {
    @Override
    public int add(int num1, int num2) {
        int result = num1+num2;
        return result;
    }

    @Override
    public int sub(int num1, int num2) {
        int result = num1-num2;
        return result;
    }

    @Override
    public int mul(int num1, int num2) {
        int result = num1*num2;
        return result;
    }

    @Override
    public int div(int num1, int num2) {
        int result = num1/num2;
        return result;
    }
}

3.配置spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--    掃包-->
    <context:component-scan base-package="com.southwind.aop"></context:component-scan>
<!--    自動代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

3測試類:

package com.southwind.aop.impl;

import com.southwind.aop.Cal;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring-aop.xml");
        Cal cal = (Cal)applicationContext.getBean("a");
        System.out.println(cal.add(10,3));
    }

}
  • @Component 將切面類加載到IoC容器中

  • @Aspect 表示類是一個切面類

  • @Before 表示方法執行的時機,execution表示的是切入點是CallImpl中執行add方法之前執行日志方法

  • @AfterReturning,表示方法的執行時機是再業務方法返回結果:returning是將返回的業務代碼的返回的形參

  • @AfterThrowing:表示方法執行是拋出的異常,throwing表示拋出的異常的處理形參

  • aop:aspectj-autoproxy ,Spring IoC容器會結合動態代理對象自動的生成代理對象,AOP底層就是通過動態代理對象來實現的。

    AOP的概念:

  • 切面對象;根據切面抽象出來的對象,Callmpl所有的方法中需要加入日志的部分,抽象成一個切面對象

  • 通知:切面對象具體執行的代碼,即具體的非業務代碼,LoggerAspect對象打印日志的代碼

  • 目標;被橫切的對象,即CallImpl將通知加入其中。

  • 代理:切面對象、通知、目標混合之后的結果,即時我門使用JDK動態代理的機制創建對象

  • 連接點;需要被橫切的位置,即要通知要插入業務代碼的具體位置

總結

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

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