spring—aop
Spring 的 AOP 簡介
什么是 AOP
AOP 為 Aspect Oriented Programming 的縮寫,意思為面向切面編程,是通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。
AOP 是 OOP 的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
AOP 的作用及其優勢
作用:在程序運行期間,在不修改源碼的情況下對方法進行功能增強
優勢:減少重復代碼,提高開發效率,并且便于維護
AOP 的底層實現
實際上,AOP 的底層是通過 Spring 提供的的動態代理技術實現的。在運行期間,Spring通過動態代理技術動態的生成代理對象,代理對象方法執行時進行增強功能的介入,在去調用目標對象的方法,從而完成功能的增強。
AOP 相關概念
-
Target(目標對象):代理的目標對象
-
Proxy (代理):一個類被 AOP 織入增強后,就產生一個結果代理類
-
Joinpoint(連接點):所謂連接點是指那些被攔截到的點。在spring中,這些點指的是方法,因為spring只支持方法類型的連接點
-
Pointcut(切入點):所謂切入點是指我們要對哪些 Joinpoint 進行攔截的定義
-
Advice(通知/ 增強):所謂通知是指攔截到 Joinpoint 之后所要做的事情就是通知
-
Aspect(切面):是切入點和通知(引介)的結合
-
Weaving(織入):是指把增強應用到目標對象來創建新的代理對象的過程。spring采用動態代理織入,而AspectJ采用編譯期織入和類裝載期織入
切點表達式的寫法
表達式語法:
execution([修飾符] 返回值類型 包名.類名.方法名(參數))-
訪問修飾符可以省略
-
返回值類型、包名、類名、方法名可以使用星號* 代表任意
-
包名與類名之間一個點 . 代表當前包下的類,兩個點 … 表示當前包及其子包下的類
-
參數列表可以使用兩個點 … 表示任意個數,任意類型的參數列表
例如:
execution(public void com.itheima.aop.Target.method()) execution(void com.itheima.aop.Target.*(..)) execution(* com.itheima.aop.*.*(..)) execution(* com.itheima.aop..*.*(..)) execution(* *..*.*(..))AOP 開發明確的事項
需要編寫的內容
-
編寫核心業務代碼(目標類的目標方法)
-
編寫切面類,切面類中有通知(增強功能方法)
-
在配置文件中,配置織入關系,即將哪些通知與哪些連接點進行結合
AOP 底層使用哪種代理方式
在 spring 中,框架會根據目標類是否實現了接口來決定采用哪種動態代理的方式。
基于 XML 的 AOP 開發
①導入 AOP 相關坐標
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.9.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version></dependency>②創建目標接口和目標類(內部有切點)
public class ImplDao implements Dao {public void save() {System.out.println("saving");}public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Dao i = (Dao) applicationContext.getBean("target");i.save();} }③創建切面類(內部有增強方法)
public class MyAspect {public void before(){System.out.println("前置");}public void after(){System.out.println("后置");}public void around(ProceedingJoinPoint proceedingJoinPoint){System.out.println("環繞");try {proceedingJoinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}System.out.println("環繞");} }④將目標類和切面類的對象創建權交給 spring
⑤在 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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:p="http://www.springframework.org/schema/p"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 "><bean id="aspect" class="com.MyAspect"/><bean id="target" class="com.ImplDao"/><aop:config ><aop:aspect ref="aspect"><aop:pointcut id="pc" expression="execution( void com.ImplDao.save(..))"/><aop:after method="after" pointcut-ref="pc"/><aop:before method="before" pointcut-ref="pc"/><aop:around method="around" pointcut-ref="pc"/></aop:aspect></aop:config></beans>⑥測試代碼
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringJunitTest {@AutowiredDao dao;@Testpublic void test(){dao.save();} }基于注解的 AOP 開發
基于注解的aop開發步驟:
①創建目標接口和目標類(內部有切點)
@Repository("impl") @Scope("singleton") public class ImplDao implements Dao {public void save() {System.out.println("saving");}public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Dao i = (Dao) applicationContext.getBean("target");i.save();} }②創建切面類(內部有增強方法)
@Component("aspect") @Aspect public class MyAspect {@Pointcut("execution( void com.ImplDao.save(..))")public void pc(){}@Before("MyAspect.pc()")public void before(){System.out.println("前置");}@After("MyAspect.pc()")public void after(){System.out.println("后置");}@Around("MyAspect.pc()")public void around(ProceedingJoinPoint proceedingJoinPoint){System.out.println("環繞");try {proceedingJoinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}System.out.println("環繞");} }③將目標類和切面類的對象創建權交給 spring
④在切面類中使用注解配置織入關系
⑤在配置文件中開啟組件掃描和 AOP 的自動代理
<?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"xmlns:p="http://www.springframework.org/schema/p"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"/><aop:aspectj-autoproxy/></beans>⑥測試
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringJunitTest {@AutowiredDao dao;@Testpublic void test(){dao.save();} }總結
以上是生活随笔為你收集整理的spring—aop的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经常梦到日本人是为什么
- 下一篇: spring—JdbcTemplate使