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

歡迎訪問 生活随笔!

生活随笔

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

javascript

Spring 面向切面编程(AOP) D5

發(fā)布時間:2024/1/8 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring 面向切面编程(AOP) D5 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Spring AOP簡介

問題提出

首先我們回顧一下OOP(Object Oriented Programming-面向?qū)ο缶幊?#xff09;,OOP引入了封裝、繼承、多態(tài)等概念建立了一種對象層次結(jié)構(gòu),用于模擬公共行為的一個集合。不過OOP允許開發(fā)者定義縱向的關(guān)系,并不適合定義橫向的關(guān)系(例如日志功能)。 日志代碼常常是橫向的散布在所有對象層次中,這種散布在各處的重復(fù)的代碼被稱為橫切(cross cutting)。如果仍然使用OOP設(shè)計,會導(dǎo)致大量的代碼重復(fù),不利于各模塊的重用。因而我們引入AOP的編程思想。

面向切面編程

AOP(Aspect Oriented Programming),即面向切面編程,可以說是OOP的補充和完善。

在面向切面編程的思想里面,把功能分為核心業(yè)務(wù)功能和周邊功能。

  • 核心業(yè)務(wù): 比如登陸、CRUD等;
  • 周邊功能: 比如性能統(tǒng)計、日志、事務(wù)管理等

上述的周邊功能在Spring的AOP思想中,被定義為切面

在AOP思想里,核心業(yè)務(wù)功能和切面功能分別獨立開發(fā),隨后把切面功能和核心業(yè)務(wù)“編織”在一起,這就叫AOP。

AOP 好處

AOP能夠?qū)⒛切┖蜆I(yè)務(wù)無關(guān),卻被業(yè)務(wù)模塊共同調(diào)用的邏輯或責任(例如事務(wù)處理、日志管理、權(quán)限控制等)封裝起來,便于減少系統(tǒng)的重復(fù)代碼,降低模塊之間的耦合度,并且有利于未來的擴展和維護。

AOP 中的概念(理解即可)

  • 切入點(Pointcut)

    在哪些類、哪些方法上切入

  • 通知(Advice)

    在方法執(zhí)行的什么時機(方法前?后?前和后?)增強什么功能

  • 切面(Aspect)

    切面 = 切入點 + 通知,即在什么時機,哪個地方,增強什么功能!

  • 織入(Weaving)

    把切面加入到對象中,并創(chuàng)建出代理對象的過程。(Spring實現(xiàn))

AOP的一個案例

也可參照我的前一篇博客: Spring 代理模式

AOP 實現(xiàn)

問題背景說明:現(xiàn)有UserService接口(提供用戶的CRUD),UserServiceImpl類(實現(xiàn)接口中方法)。如下:(均在service包下)

package service;public interface UserService {public void add();public void delete();public void update();public void select(); } package service;public class UserServiceImpl implements UserService {public void add() {System.out.println("增加了一個用戶");}public void delete() {System.out.println("刪除了一個用戶");}public void update() {System.out.println("更新信息");}public void select() {System.out.println("查詢用戶");} }

需求: 對方法的執(zhí)行實現(xiàn)追蹤,即添加簡易的日志功能!

注意: 使用aop織入,需要引入相應(yīng)的依賴,代碼如下:

<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version> </dependency>

方法一(使用原生Spring API接口)

首先創(chuàng)建log包,創(chuàng)建兩個類:Log 、 AfterLog,分別實現(xiàn)相應(yīng)的接口。代碼如下:

Log:

package log;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class Log implements MethodBeforeAdvice {//method:要執(zhí)行的目標對象的方法//objects: 參數(shù)//target: 目標對象public void before(Method method, Object[] objects, Object target) throws Throwable {System.out.println(o.getClass().getName()+"的"+method.getName()+"被執(zhí)行了!");} }

AfterLog:

package log;import org.springframework.aop.AfterReturningAdvice;import java.lang.reflect.Method;public class AfterLog implements AfterReturningAdvice {public void afterReturning(Object returnValue, Method method, Object[] objects, Object target) throws Throwable {System.out.println("執(zhí)行了"+method.getName()+",返回結(jié)果為:"+returnValue);} }

applicationContext.xml中配置:(放在resources包下)

<?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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--注冊bean--><bean id="userService" class="com.demut.service.UserServiceImpl"/><bean id="log" class="com.demut.log.Log"/><bean id="afterLog" class="com.demut.log.AfterLog"/><!--方式一: 使用原生Spring API接口--><!--配置aop: 需要導(dǎo)入aop的約束--><aop:config><!--切入點 : expression: 表達式,execution(要執(zhí)行的位置!* * * * *)--><aop:pointcut id="pointcut" expression="execution(* com.demut.service.UserServiceImpl.*(..))"/><!--執(zhí)行環(huán)繞增加!--><aop:advisor advice-ref="log" pointcut-ref="pointcut"/><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/></aop:config></beans>

測試類:

import com.demut.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//動態(tài)代理 代理的是接口!!!UserService userService = context.getBean("userService", UserService.class);userService.select();} }

運行結(jié)果:

此方法中重點關(guān)注,applicationContext.xml中配置!

方法二(自定義類來實現(xiàn))

創(chuàng)建diy包,在內(nèi)部創(chuàng)建類:DiyPointCut,類中內(nèi)容如下:

package com.demut.diy;public class DiyPointCut {public void before() {System.out.println("************方法執(zhí)行前************");}public void after() {System.out.println("************方法執(zhí)行后************");} }

修改applicationContext.xml中內(nèi)容為:

<?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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--注冊bean--><bean id="userService" class="com.demut.service.UserServiceImpl"/><bean id="log" class="com.demut.log.Log"/><bean id="afterLog" class="com.demut.log.AfterLog"/><!--方式二:自定義類--><bean id="diy" class="com.demut.diy.DiyPointCut"/><aop:config><!--自定義切面ref要引用的類--><aop:aspect ref="diy"><!--切入點--><aop:pointcut id="point" expression="execution(* com.demut.service.UserServiceImpl.*(..))"/><!--通知--><aop:before method="before" pointcut-ref="point"/><aop:after method="after" pointcut-ref="point"/></aop:aspect></aop:config></beans>

測試結(jié)果:

方法三(使用注解實現(xiàn))

使用到的注解:

  • @Aspect
  • @Before
  • @After
  • @Around

在diy包下新建類: AnnotationPointCut類:

package com.demut.diy;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before;@Aspect //標注這個類是一個切面 public class AnnotationPointCut {@Before("execution(* com.demut.service.UserServiceImpl.*(..))")public void before() {System.out.println("==============方法執(zhí)行前==============");}@After("execution(* com.demut.service.UserServiceImpl.*(..))")public void after() {System.out.println("==============方法執(zhí)行后==============");}//在環(huán)繞增強中,我們可以給定一個參數(shù),代表我們要獲取處理切入的點@Around("execution(* com.demut.service.UserServiceImpl.*(..))")public void around(ProceedingJoinPoint jp) throws Throwable {System.out.println("環(huán)繞前");//獲取簽名~獲取執(zhí)行的是哪個類中的哪個方法Signature signature = jp.getSignature();System.out.println(signature);//執(zhí)行方法Object proceed = jp.proceed();System.out.println("環(huán)繞后");} }

在applicationContext.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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--注冊bean--><bean id="userService" class="com.demut.service.UserServiceImpl"/><bean id="log" class="com.demut.log.Log"/><bean id="afterLog" class="com.demut.log.AfterLog"/><!--方式三:使用注解--><bean id="annotationPointCut" class="com.demut.diy.AnnotationPointCut"/><!--開啟注解支持--><aop:aspectj-autoproxy/></beans>

測試結(jié)果:

【參考文章】

https://www.cnblogs.com/xrq730/p/4919025.html

https://www.jianshu.com/p/994027425b44

寫在最后

瀑布的水逆流而上,

蒲公英種子從遠處飄回,聚成傘的模樣,

太陽從西邊升起,落向東方。

子彈退回槍膛,

運動員回到起跑線上,

我交回錄取通知書,忘了十年寒窗。

廚房里飄來飯菜的香,

你把我的卷子簽好名字,

關(guān)掉電視,幫我把書包背上

你還在我身旁。

? ——戴暢

總結(jié)

以上是生活随笔為你收集整理的Spring 面向切面编程(AOP) D5的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。