天天看點

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

Spring5——AOP介紹

  • 1、AOP(概念)
  • 2、AOP(底層原理)
  • 3、AOP(JDK 動态代理)
  • 4、AOP(術語)
  • 5、AOP 操作(準備工作)
  • 6、AOP 操作(基于AspectJ 注解)
  • 7、AOP 操作(基于AspectJ 配置檔案)

1、AOP(概念)

1、什麼是 AOP

(1)面向切面程式設計(方面),利用 AOP 可以對業務邏輯的各個部分進行隔離,進而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。

(2)通俗描述:不通過修改源代碼方式,在主幹功能裡面添加新功能

(3)使用登入例子說明 AOP

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

2、AOP(底層原理)

1、AOP 底層使用動态代理

(1)有兩種情況動态代理

第一種 有接口情況,使用 JDK 動态代理

建立接口實作類代理對象,增強類的方法

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

第二種 沒有接口情況,使用 CGLIB 動态代理

建立子類的代理對象,增強類的方法

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

3、AOP(JDK 動态代理)

1、使用 JDK 動态代理,使用 Proxy 類裡面的方法建立代理對象

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

(1)調用 newProxyInstance 方法

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

方法有三個參數:

第一參數,類加載器

第二參數,增強方法所在的類,這個類實作的接口,支援多個接口

第三參數,實作這個接口 InvocationHandler,建立代理對象,寫增強的部分

2、編寫 JDK 動态代理代碼

(1)建立接口,定義方法

public interface UserDao {
	 public int add(int a,int b);
	 public String update(String id);
}
           

(2)建立接口實作類,實作方法

public class UserDaoImpl implements UserDao {
	 @Override
	 public int add(int a, int b) {
		 return a+b;
	 }
	 
	 @Override
	 public String update(String id) {
		 return id;
	 }
}
           

(3)使用 Proxy 類建立接口代理對象

public class JDKProxy {

    public static void main(String[] args) {
        //建立接口實作類代理對象
        Class[] interfaces = {UserDao.class};
//        Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() {
//            @Override
//            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                return null;
//            }
//        });
        UserDaoImpl userDao = new UserDaoImpl();
        UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
        int result = dao.add(1, 2);
        System.out.println("result:" + result);
    }
}

//建立代理對象代碼
class UserDaoProxy implements InvocationHandler {

    //1 把建立的是誰的代理對象,把誰傳遞過來
    //有參數構造傳遞
    private Object obj;

    public UserDaoProxy(Object obj) {
        this.obj = obj;
    }

    //增強的邏輯
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前
        System.out.println("方法之前執行...." + method.getName() + " :傳遞的參數..." + Arrays.toString(args));

        //被增強的方法執行
        Object res = method.invoke(obj, args);

        //方法之後
        System.out.println("方法之後執行...." + obj);
        return res;
    }
}
           

4、AOP(術語)

1、連接配接點

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

2、切入點

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

3、通知(增強)

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)
Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

4、切面

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

5、AOP 操作(準備工作)

1、Spring 架構一般都是基于 AspectJ 實作 AOP 操作

(1)AspectJ 不是 Spring 組成部分,獨立于 AOP 架構,一般把 AspectJ 和 Spirng 架構一起使用,進行 AOP 操作

2、基于 AspectJ 實作 AOP 操作

(1)基于 xml 配置檔案實作

(2)基于注解方式實作(使用)

3、在項目工程裡面引入 AOP 相關依賴

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

4、切入點表達式

(1)切入點表達式作用:知道對哪個類裡面的哪個方法進行增強

(2)文法結構: execution([權限修飾符] [傳回類型] [類全路徑] [方法名稱]([參數清單]) )

舉例 1:對 com.atguigu.dao.BookDao 類裡面的 add 進行增強

execution(* com.atguigu.dao.BookDao.add(…))

舉例 2:對 com.atguigu.dao.BookDao 類裡面的所有的方法進行增強

execution(* com.atguigu.dao.BookDao.* (…))

舉例 3:對 com.atguigu.dao 包裡面所有類,類裡面所有方法進行增強

execution(* com.atguigu.dao.. (…))

6、AOP 操作(基于AspectJ 注解)

1、建立類,在類裡面定義方法

public class User {
	 public void add() {
		 System.out.println("add.......");
	 }
}
           

2、建立增強類(編寫增強邏輯)

(1)在增強類裡面,建立方法,讓不同方法代表不同通知類型

//增強的類
public class UserProxy {
	 public void before() {//前置通知
	 	System.out.println("before......");
	 }
}
           

3、進行通知的配置

(1)在 spring 配置檔案中,開啟注解掃描

<?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 http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 開啟注解掃描 -->
    <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan>

           

(2)使用注解建立 User 和 UserProxy 對象

Spring5——AOP介紹1、AOP(概念)2、AOP(底層原理)3、AOP(JDK 動态代理)4、AOP(術語)5、AOP 操作(準備工作)6、AOP 操作(基于AspectJ 注解)7、AOP 操作(基于AspectJ 配置檔案)

(3)在增強類上面添加注解 @Aspect

//增強的類
@Component
@Aspect //生成代理對象
public class UserProxy {
           

(4)在 spring 配置檔案中開啟生成代理對象

<!-- 開啟Aspect生成代理對象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
           
//增強的類
@Component
@Aspect  //生成代理對象
@Order(3)
public class UserProxy {

    //相同切入點抽取
    @Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void pointdemo() {

    }

    //前置通知
    //@Before注解表示作為前置通知
    @Before(value = "pointdemo()")
    public void before() {
        System.out.println("before.........");
    }

    //後置通知(傳回通知)
    @AfterReturning(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterReturning() {
        System.out.println("afterReturning.........");
    }

    //最終通知
    @After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void after() {
        System.out.println("after.........");
    }

    //異常通知
    @AfterThrowing(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterThrowing() {
        System.out.println("afterThrowing.........");
    }

    //環繞通知
    @Around(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("環繞之前.........");

        //被增強的方法執行
        proceedingJoinPoint.proceed();

        System.out.println("環繞之後.........");
    }
}
           

5、相同的切入點抽取

//相同切入點抽取
@Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
public void pointdemo() {
}

//前置通知
//@Before 注解表示作為前置通知
@Before(value = "pointdemo()")
public void before() {
	 System.out.println("before.........");
}
           

6、有多個增強類多同一個方法進行增強,設定增強類優先級

(1)在增強類上面添加注解 @Order(數字類型值),數字類型值越小優先級越高

@Component
@Aspect
@Order(1)
public class PersonProxy
           

7、完全使用注解開發

(1)建立配置類,不需要建立 xml 配置檔案

@Configuration
@ComponentScan(basePackages = {"com.atguigu"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigAop {
}
           

7、AOP 操作(基于AspectJ 配置檔案)

1、建立兩個類,增強類和被增強類,建立方法

2、在 spring 配置檔案中建立兩個類對象

<!--建立對象-->
<bean id="book" class="com.atguigu.spring5.aopxml.Book"></bean>
<bean id="bookProxy" class="com.atguigu.spring5.aopxml.BookProxy"></bean>
           

3、在 spring 配置檔案中配置切入點

<!--配置aop增強-->
    <aop:config>
        <!--切入點-->
        <aop:pointcut id="p" expression="execution(* com.atguigu.spring5.aopxml.Book.buy(..))"/>
        <!--配置切面-->
        <aop:aspect ref="bookProxy">
            <!--增強作用在具體的方法上-->
            <aop:before method="before" pointcut-ref="p"/>
        </aop:aspect>
    </aop:config>
           

以上就是關于Spring5——AOP的介紹,如果有不當之處或者遇到什麼問題,歡迎在文章下面留言~

如果你想了解更多關于JavaWeb的内容,可以檢視:SSM架構學習目錄