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

2、AOP(底層原理)
1、AOP 底層使用動态代理
(1)有兩種情況動态代理
第一種 有接口情況,使用 JDK 動态代理
建立接口實作類代理對象,增強類的方法
第二種 沒有接口情況,使用 CGLIB 動态代理
建立子類的代理對象,增強類的方法
3、AOP(JDK 動态代理)
1、使用 JDK 動态代理,使用 Proxy 類裡面的方法建立代理對象
(1)調用 newProxyInstance 方法
方法有三個參數:
第一參數,類加載器
第二參數,增強方法所在的類,這個類實作的接口,支援多個接口
第三參數,實作這個接口 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、連接配接點
2、切入點
3、通知(增強)
4、切面
5、AOP 操作(準備工作)
1、Spring 架構一般都是基于 AspectJ 實作 AOP 操作
(1)AspectJ 不是 Spring 組成部分,獨立于 AOP 架構,一般把 AspectJ 和 Spirng 架構一起使用,進行 AOP 操作
2、基于 AspectJ 實作 AOP 操作
(1)基于 xml 配置檔案實作
(2)基于注解方式實作(使用)
3、在項目工程裡面引入 AOP 相關依賴
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 對象
(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架構學習目錄