java網路程式設計基礎
阿新 • • 發佈:2020-11-28
Spring AOP
3.1 Spring AOP簡介
3.1.1 AOP
Aspect-Oriented Programming,面向切面程式設計。是傳統的OOP程式設計的一個重要的補充。OOP程式設計,只能子類繼承父類的縱向重用。
AOP採用的是橫向抽取機制。將分散重複的程式碼抽離出來,在程式編譯或者執行的過程,將程式碼用到需要的執行地方。
3.1.2 AOP術語
Aspect(切面)
JoinPoint(連線點)
Pointcut(切入點)
Advice(通知增強處理)
Target Object(目標物件)
Proxy(代理)
Weaving(織入)
3.2 AspectJ開發
基於XML配置
1.UserDao.java
package com.sty.dao;
public interface UserDao {
//新增使用者
void add();
//刪除使用者
void delete();
}
2.UserDaoImpl.java
package com.sty.dao; public class UserDaoImpl implements UserDao { public void add() { System.out.println("增加一個使用者"); } public void delete() { System.out.println("刪除一個使用者"); } }
3.MyAspect.java
package com.sty.dao.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.lang.NonNull; /* * 面向切面類 * */ public class MyAspect { /*1.前置通知*/ public void myBefore(@NonNull JoinPoint joinPoint){ System.out.println("前置通知:模擬執行許可權。。。。。"); System.out.println("目標類是:"+joinPoint.getTarget()); System.out.println(","+"被植入增強處理的目標方法是"+joinPoint.getSignature().getName()); } /*2.後置通知*/ public void myAfterReturning(@NonNull JoinPoint joinPoint){ System.out.println("後置通知:模擬記錄日誌"); System.out.println("被植入增強處理的目標方法是"+joinPoint.getSignature().getName()); } /*3.環繞通知 * ProceedingJoinPoint 是JoinPoint子介面,表示可執行的目標方法 * 1. 必須是Object返回值 * 2. 引數必須是ProceedingJoinPoint型別 * 3.必須throws Throwable * * * */ public Object myAround(@NonNull ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("環繞開始:執行目標方法之前,模擬開啟事務‘。。。。"); //執行當前的方法 Object proceed = proceedingJoinPoint.proceed(); System.out.println("環繞結束:執行目標方法之後,模擬關閉事務‘。。。。"); return proceed; } /*4.異常通知*/ public void myAfterThrowing( JoinPoint joinPoint, @NonNull Throwable throwable){ System.out.println("異常通知:出錯了"+ throwable.getMessage()); } /*5.最終通知*/ public void myAfter(){ System.out.println("模擬方法,釋放資源"); } }
4.ApplicationContext.xml
<?xml version="1.0" encoding="UTF8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns="http://www.springframework.org/schema/beans"
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">
<!--1.目標類-->
<bean id="userDao" class="com.sty.dao.UserDaoImpl"/>
<!--2.切面-->
<bean id="myAspect" class="com.sty.dao.aspect.MyAspect"/>
<!--3.Aop程式設計-->
<aop:config>
<!--3.1配置切面-->
<aop:aspect id="aspect" ref="myAspect">
<!--3.2配置切點-->
<aop:pointcut id="myPointCut" expression="execution(* com.sty.dao.UserDaoImpl.add(..))"/>
<!--3.3配置通知-->
<aop:before method="myBefore" pointcut-ref="myPointCut"/>
<aop:around method="myAround" pointcut-ref="myPointCut"/>
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="returnVal"/>
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="throwable"/>
<aop:after method="myAfter" pointcut-ref="myPointCut"/>
</aop:aspect>
</aop:config>
</beans>
5.測試
public class MyTest2 {
/*自定義切面*/
@Test
public void TestDiy() {
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
UserDao userDao = (UserDao) context.getBean("userDao");
userDao.add();
System.out.println("------------------");
userDao.delete();
註解配置
1.UserDao
package com.sty.AnnotationDao;
import org.springframework.stereotype.Repository;
public interface UserDao {
//新增使用者
void add();
//刪除使用者
void delete();
}
2.UserDaoImpl.java
package com.sty.AnnotationDao;
import org.springframework.stereotype.Repository;
@Repository("userDao")
public class UserDaoImpl implements UserDao {
public void add() {
System.out.println("增加一個使用者");
}
public void delete() {
System.out.println("刪除一個使用者");
}
}
3.myAspect.java
package com.sty.AnnotationDao.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
/*
* 面向切面類
* */
@Component
@Aspect //定義一個切面
public class MyAspect {
/*定義一個表示式*/
@Pointcut("execution(* com.sty.AnnotationDao.*.*(..))")
public void myPointCut(){}
/*1.前置通知*/
@Before("myPointCut()")
public void myBefore(@NonNull JoinPoint joinPoint){
System.out.println("前置通知:模擬執行許可權。。。。。");
System.out.println("目標類是:"+joinPoint.getTarget());
System.out.println(","+"被植入增強處理的目標方法是"+joinPoint.getSignature().getName());
}
/*2.後置通知*/
@After("myPointCut()")
public void myAfterReturning(@NonNull JoinPoint joinPoint){
System.out.println("後置通知:模擬記錄日誌");
System.out.println("被植入增強處理的目標方法是"+joinPoint.getSignature().getName());
}
/*3.環繞通知
* ProceedingJoinPoint 是JoinPoint子介面,表示可執行的目標方法
* 1. 必須是Object返回值
* 2. 引數必須是ProceedingJoinPoint型別
* 3.必須throws Throwable
*
*
* */
@Around("myPointCut()")
public Object myAround(@NonNull ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("環繞開始:執行目標方法之前,模擬開啟事務‘。。。。");
//執行當前的方法
Object proceed = proceedingJoinPoint.proceed();
System.out.println("環繞結束:執行目標方法之後,模擬關閉事務‘。。。。");
return proceed;
}
/*4.異常通知*/
@AfterThrowing(value = "myPointCut()",throwing = "throwable")
public void myAfterThrowing( JoinPoint joinPoint, @NonNull Throwable throwable){
System.out.println("異常通知:出錯了"+ throwable.getMessage());
}
/*5.最終通知*/
@After("myPointCut()")
public void myAfter(){
System.out.println("模擬方法,釋放資源");
}
}
4.application.xml
<?xml version="1.0" encoding="UTF8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns="http://www.springframework.org/schema/beans"
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.sty"/>
<!--啟動基於註解的聲名式Aspect支援-->
<aop:aspectj-autoproxy/>
</beans>