前言:這個文章的定位不是實現的步驟,而是實現過程中遇到的問題。並且我寫的步驟是別人的步驟的記錄,算不了什麼,後面對使用過程中遇到的問題以及解決的方法纔是自己寫的,有價值的地方。
寫這篇文章的出發點一個是爲了保障自己學以致用,一個是查漏補缺。
而且很多教程雖然說按照那個步驟可以成功,但也可能不成功,要麼是自己操作有誤,要麼是版本變了,還有可能自己基礎沒學好,前置知識不夠。我最開始寫Java的時候連創建父類和接口類都不會,直接創建一個類,然後複製粘貼,最後報錯。僵硬~
寫這類博客,即寫步驟,又寫操作過程中遇到的問題,然後從中吸取教訓,可以讓成功的概率更大。
同時sprig框架學習我打算按照五部分(IOC、bean、AOP、數據庫、事務)進行梳理,最後加個綜合大應用。學前在注意的情況下,會寫前置知識。
Java基礎:https://blog.csdn.net/weixin_42875245/article/details/105951858
IDE使用:https://blog.csdn.net/weixin_42875245/article/details/105867499
Spring學習筆記:https://blog.csdn.net/weixin_42875245/article/details/105631818
Spring見解:https://blog.csdn.net/Haidaiya/article/details/105611801
一、引入包
1在eclipse基礎開發環境創建一個springtest03的動態web項目,將spring的4個基本包以及commons-logging的包,還有spring-aop-4.3.6.RELEASE.jar、spring-aspects-4.3.6.RELEASE.jar、aspectjweaver-1.8.10.jar複製到lib目錄中,併發布到類路徑下。
二、基於XML的聲明式AspectJ
1在src創建一個com.ssm.aspectj包,在包中創建接口UserDAO,並在接口中編寫添加和刪除的方法。代碼如下:
2在com.ssm.aspectj包中創建接口實現類UserDaoImpl,並實現接口中的方法。代碼如下:
3在src目錄下創建在com.ssm.aspectj.xml包,在包中創建切面類MyAspect,並在類中分別定義不同類型的 通知。代碼如下
4在com.ssm.aspectj.xml包中創建配置文件applicationContext.xml,並編寫相關配置,代碼如下。
5在com.ssm.aspectj.xml包中創建測試類TestXmlAspectJ,代碼如下
6測試:
三、基於註解的聲明式aspectj
1在src目錄下創建在com.ssm.aspectj.annotation包,在包中創建切面類MyAspect。代碼如下。(在UserDaoImpl中添加註解@Repository(“UserDao”))
2在com.ssm.aspectj.annotation包中創建配置文件applicationContext.xml,並編寫相關配置,代碼如下。
3在com.ssm.aspectj.annotation包中創建測試類TestAnotation,代碼如下
4測試:
與XML相比,使用註解的方式更加方便和簡單,且可以不用寫實現AOP功能所配置的代碼,提高開發效率。
四、第一個實驗
1創建接口類UserDao
package com.ssm.aspectj;
public interface UserDao {
public void addUser();
public void deleteUser();
}
2創建接口實現類UserDaoImpl
package com.ssm.aspectj;
import org.springframework.stereotype.Repository;
@Repository("userDao")//用於註解方式
public class UserDaoImpl implements UserDao {
public void addUser() {
System.out.println("添加用戶");
// 用於設置異常
// int i=10/0;
}
public void deleteUser() {
System.out.println("刪除用戶");
}
}
3創建MyAspect類
package com.ssm.aspectj.xml;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 切面類,在此類中編寫通知
*/
public class MyAspect {
//前置通知
public void myBefore(JoinPoint joinPoint){
System.out.print("前置通知:模擬執行權限檢查..,");
System.out.print("目標類是:"+joinPoint.getTarget());
System.out.println(",被植入增強處理的目標方法爲:"+joinPoint.getSignature().getName());
}
//後置通知
public void myAfterReturning(JoinPoint joinPoint) {
System.out.print("後置通知:模擬記錄日誌..,");
System.out.println("被植入增強處理的目標方法爲:" + joinPoint.getSignature().getName());
}
/**
* 環繞通知
* ProceedingJoinPoint是JoinPoint的子接口,表示可執行目標方法
* 1.必須是Object類型的返回值
* 2.必須接收一個參數,類型爲ProceedingJoinPoint
* 3.必須throws Throwable
*/
public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
//開始
System.out.println("環繞開始:執行目標方法之前,模擬開啓事務..,");
//執行當前目標方法
Object obj=proceedingJoinPoint.proceed();
//結束
System.out.println("環繞結束:執行目標方法之後,模擬關閉事務..,");
return obj;
}
//異常通知
public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
System.out.println("異常通知:出錯了"+e.getMessage());
}
//最終通知
public void myAfter(){
System.out.println("最終通知:模擬方法結束後釋放資源..");
}
}
4創建配置文件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/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 1 目標類 -->
<bean id="userDao" class="com.ssm.aspectj.UserDaoImpl" />
<!-- 2 切面 -->
<bean id="myAspect" class="com.ssm.aspectj.xml.MyAspect" />
<!-- 3 aop編程 -->
<aop:config>
<!-- 1.配置切面 -->
<aop:aspect id="aspect" ref="myAspect">
<!-- 2.配置切入點 -->
<aop:pointcut expression="execution(* com.ssm.aspectj.*.*(..))" id="myPointCut" />
<!-- 3.配置通知 -->
<!-- 前置通知 -->
<aop:before method="myBefore" pointcut-ref="myPointCut" />
<!--後置通知-->
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="returnVal"/>
<!--環繞通知 -->
<aop:around method="myAround" pointcut-ref="myPointCut" />
<!--異常通知 -->
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e" />
<!--最終通知 -->
<aop:after method="myAfter" pointcut-ref="myPointCut" />
</aop:aspect>
</aop:config>
</beans>
5創建測試類TestXmlAprectJ
package com.ssm.aspectj.xml;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ssm.aspectj.UserDao;
public class TestXmlAspectJ {
public static void main(String[] args) {
String xmlPath="com/ssm/aspectj/xml/applicationContext.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
//從容器中獲得內容
UserDao userDao=(UserDao)applicationContext.getBean("userDao");
//執行方法
userDao.addUser();
}
}
五、第二個實驗
1創建切面類
package com.ssm.aspectj.annotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* 切面類,在此類中編寫通知
*/
@Aspect
@Component
public class MyAspect {
//定義切入點表達式
@Pointcut("execution(* com.ssm.aspectj.*.*(..))")
//使用一個返回值爲void、方法體爲空的方法來命名切入點
public void myPointCut(){}
//前置通知
@Before("myPointCut()")
public void myBefore(JoinPoint joinPoint){
System.out.print("前置通知:模擬執行權限檢查..,");
System.out.print("目標類是:"+joinPoint.getTarget());
System.out.println(",被植入增強處理的目標方法爲:"+joinPoint.getSignature().getName());
}
//後置通知
@AfterReturning(value="myPointCut()")
public void myAfterReturning(JoinPoint joinPoint) {
System.out.print("後置通知:模擬記錄日誌..,");
System.out.println("被植入增強處理的目標方法爲:" + joinPoint.getSignature().getName());
}
/**
* 環繞通知
* ProceedingJoinPoint是JoinPoint的子接口,表示可執行目標方法
* 1.必須是Object類型的返回值
* 2.必須接收一個參數,類型爲ProceedingJoinPoint
* 3.必須throws Throwable
*/
@Around("myPointCut()")
public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
//開始
System.out.println("環繞開始:執行目標方法之前,模擬開啓事務..,");
//執行當前目標方法
Object obj=proceedingJoinPoint.proceed();
//結束
System.out.println("環繞結束:執行目標方法之後,模擬關閉事務..,");
return obj;
}
//異常通知
@AfterThrowing(value="myPointCut()",throwing="e")
public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
System.out.println("異常通知:出錯了"+e.getMessage());
}
//最終通知
@After("myPointCut()")
public void myAfter(){
System.out.println("最終通知:模擬方法結束後釋放資源..");
}
}
2創建配置文件
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 指定需要掃描的包,使註解生效 -->
<context:component-scan base-package="com.ssm" />
<!-- 啓動基於註解的聲明式AspectJ支持 -->
<aop:aspectj-autoproxy />
</beans>
3創建測試類
package com.ssm.aspectj.annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ssm.aspectj.UserDao;
public class TestAnnotation {
public static void main(String[] args) {
String xmlPath="com/ssm/aspectj/annotation/applicationContext.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
//從容器中獲得內容
UserDao userDao=(UserDao)applicationContext.getBean("userDao");
//執行方法
userDao.addUser();
}
}
結論:有些僵硬,沒遇到問題,還想着與報錯鬥智鬥勇。回頭從eclipse轉IDEA試試。