目錄
一、注解配置AOP
1. 開啟注解支持
2. 在類和方法加入注解
3. 測試
4.??為一個類下的所有方法統(tǒng)一配置切點
二、原生Spring實現(xiàn)AOP
1. 引入依賴
2. 編寫SpringAOP通知類
3. 編寫配置類bean2.xml
4? 測試
三、SchemaBased實現(xiàn)AOP
1. 配置切面
2. 測試
往期專欄&文章相關(guān)導(dǎo)讀?
1. Maven系列專欄文章
2. Mybatis系列專欄文章
3. Spring系列專欄文章
一、注解配置AOP
Spring可以使用注解代替配置文件配置切面:
1. 開啟注解支持
在xml中開啟AOP注解支持
以下是bean1.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.example"></context:component-scan> <!-- 開啟注解配置Aop --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
2. 在類和方法加入注解
在通知類上方加入注解 @Aspect:配置切面
在通知方法上方加入注解
- @Before:前置通知
- @AfterReturning:后置通知
- @AfterThrowing:異常通知
- @After:最終通知
- @Around:環(huán)繞通知
MyAspectAdvice通知類?
package com.example.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspectJAdvice {
// 后置通知
@AfterReturning("execution(* com.example.dao.UserDao.*(..))")
public void myAfterReturning(JoinPoint joinPoint){
System.out.println("切點方法名:"+joinPoint.getSignature().getName());
System.out.println("目標(biāo)對象:"+joinPoint.getTarget());
System.out.println("打印日志···"+joinPoint.getSignature().getName()+"方法被執(zhí)行了!");
}
// 前置通知
@Before("execution(* com.example.dao.UserDao.*(..))")
public void myBefore(){
System.out.println("前置通知···");
}
// 異常通知
@AfterThrowing(value = "execution(* com.example.dao.UserDao.*(..))",throwing = "e")
public void myAfterThrowing(Exception e){
System.out.println("異常通知···");
System.out.println(e.getMessage());
}
// 最終通知
@After("execution(* com.example.dao.UserDao.*(..))")
public void myAfter(){
System.out.println("最終通知···");
}
// 環(huán)繞通知
@Around("execution(* com.example.dao.UserDao.*(..))")
public Object myAround(ProceedingJoinPoint point) throws Throwable {
System.out.println("環(huán)繞前···");
// 執(zhí)行方法
Object obj = point.proceed();
System.out.println("環(huán)繞后···");
return obj;
}
}
3. 測試
測試方法
// 測試注解開發(fā)AOP
@Test
public void testAdd2(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
//userDao.update();
userDao.delete();
}
測試結(jié)果(無異常):?
使用update方法測試結(jié)果(有異常):?
可以看到環(huán)繞后沒有打印,因為此時碰到異常終止了程序?
4.??為一個類下的所有方法統(tǒng)一配置切點
如何為一個類下的所有方法統(tǒng)一配置切點:
在通知類中添加方法配置切點
// 添加方法配置切點 @Pointcut("execution(* com.example.dao.UserDao.*(..))") public void pointcut(){ }
在通知方法上使用定義好的切點,就是把注解括號里面得內(nèi)容替換成?"pointCut()"?即可。
二、原生Spring實現(xiàn)AOP
除了AspectJ,Spring支持原生方式實現(xiàn)AOP。但是要注意的是原生方式實現(xiàn)AOP只有四種通知類型:前置通知、后置通知、環(huán)繞通知,異常通知。少了最終通知。
1. 引入依賴
<!-- AOP -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.13</version>
</dependency>
2. 編寫SpringAOP通知類
Spring原生方式實現(xiàn)AOP時,只支持四種通知類型:
通知類型 實現(xiàn)接口 前置通知 MethodBeforeAdvice 后置通知 AfterReturningAdvice 異常通知 ThrowsAdvice 環(huán)繞通知 MethodInterceptor
package com.example.aspect;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;
import java.lang.reflect.Method;
public class SpringAop implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice, MethodInterceptor {
/**
* 環(huán)繞通知
* @param invocation 目標(biāo)方法
* @return
* @throws Throwable
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("環(huán)繞前");
Object proceed = invocation.proceed();
System.out.println("環(huán)繞后");
return proceed;
}
/**
* 后置通知
* @param returnValue 目標(biāo)方法的返回值
* @param method 目標(biāo)方法
* @param args 目標(biāo)方法的參數(shù)列表
* @param target 目標(biāo)對象
* @throws Throwable
*/
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("后置通知");
}
/**
* 前置通知
* @param method 目標(biāo)方法
* @param args 目標(biāo)方法的參數(shù)列表
* @param target 目標(biāo)對象
* @throws Throwable
*/
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置通知");
}
/**
* 異常通知
* @param e 異常對象
*/
public void afterThrowing(Exception e){
System.out.println("發(fā)生異常了!");
}
}
3. 編寫配置類bean2.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.example"></context:component-scan>
<!-- 通知對象 -->
<bean id="springAop" class="com.example.aspect.SpringAop"/>
<!-- 配置代理對象 -->
<bean id="userDaoProxy"class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 配置目標(biāo)對象 -->
<property name="target" ref="userDao"/>
<!-- 配置通知 -->
<property name="interceptorNames">
<list>
<value>springAop</value>
</list>
</property>
<!-- 代理對象的生成方式 true:使用CGLib false:使用原生JDK生成 -->
<property name="proxyTargetClass" value="true"/>
<!-- bug -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</bean>
</beans>
4? 測試
測試類UserDaoTest2
import com.example.dao.UserDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class userDaoTest2 {
// 原生AOP測試
@Test
public void testAdd(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean2.xml");
UserDao userDao = (UserDao) ac.getBean("userDaoProxy");
userDao.update();
}
}
測試結(jié)果?
????????OK,這里有個驚喜,如果敲到這里同學(xué),就知道了?
????????其實標(biāo)簽?zāi)莻€bug,是因為原生方法配置類要加上那個標(biāo)簽才可以識別,否則會報一個錯誤。
三、SchemaBased實現(xiàn)AOP
????????SchemaBased(基礎(chǔ)模式)配置方式是指使用Spring原生方式定義通知,而使用AspectJ框架配置切面。因此這里通知類和上面一樣,看上面的即可。
1. 配置切面
aop3.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.example"></context:component-scan>
<!-- 通知對象 -->
<bean id="springAop2" class="com.example.aspect.SpringAop"/>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切點 -->
<aop:pointcut id="myPointcut" expression="execution(* com.example.dao.UserDao.*(..))"/>
<!-- 配置切面:advice-ref:通知對象 pointcut-ref:切點 -->
<aop:advisor advice-ref="springAop2" pointcut-ref="myPointcut"/>
</aop:config>
</beans>
2. 測試
測試方法
// 使用AspectJ框架配置切面測試
@Test
public void t6(){
ApplicationContext ac = new ClassPathXmlApplicationContext("aop3.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
userDao.add();
}
測試結(jié)果
????????OK,這里的輸出應(yīng)該是我上面定義的不夠完美,有些可能重復(fù)定義了,所以這里就重復(fù)輸出了一些東西?文章來源:http://www.zghlxwxcb.cn/news/detail-472868.html
往期專欄&文章相關(guān)導(dǎo)讀?
?????大家如果對于本期內(nèi)容有什么不了解的話也可以去看看往期的內(nèi)容,下面列出了博主往期精心制作的Maven,Mybatis等專欄系列文章,走過路過不要錯過哎!如果對您有所幫助的話就點點贊,收藏一下啪。其中Spring專欄有些正在更,所以無法查看,但是當(dāng)博主全部更完之后就可以看啦。文章來源地址http://www.zghlxwxcb.cn/news/detail-472868.html
1. Maven系列專欄文章
Maven系列專欄 | Maven工程開發(fā) |
Maven聚合開發(fā)【實例詳解---5555字】 |
2. Mybatis系列專欄文章
Mybatis系列專欄 | MyBatis入門配置 |
Mybatis入門案例【超詳細(xì)】 | |
MyBatis配置文件 —— 相關(guān)標(biāo)簽詳解 | |
Mybatis模糊查詢——三種定義參數(shù)方法和聚合查詢、主鍵回填 | |
Mybatis動態(tài)SQL查詢 --(附實戰(zhàn)案例--8888個字--88質(zhì)量分) | |
Mybatis分頁查詢——四種傳參方式 | |
Mybatis一級緩存和二級緩存(帶測試方法) | |
Mybatis分解式查詢 | |
Mybatis關(guān)聯(lián)查詢【附實戰(zhàn)案例】 | |
MyBatis注解開發(fā)---實現(xiàn)增刪查改和動態(tài)SQL | |
MyBatis注解開發(fā)---實現(xiàn)自定義映射關(guān)系和關(guān)聯(lián)查詢 |
3. Spring系列專欄文章
Spring系列專欄 | Spring IOC 入門簡介【自定義容器實例】 |
IOC使用Spring實現(xiàn)附實例詳解 | |
Spring IOC之對象的創(chuàng)建方式、策略及銷毀時機和生命周期且獲取方式 | |
Spring DI簡介及依賴注入方式和依賴注入類型 | |
Spring IOC相關(guān)注解運用——上篇 | |
Spring IOC相關(guān)注解運用——下篇 | |
Spring AOP簡介及相關(guān)案例 | |
注解、原生Spring、SchemaBased三種方式實現(xiàn)AOP【附詳細(xì)案例】 | |
Spring事務(wù)簡介及相關(guān)案例 | |
Spring 事務(wù)管理方案和事務(wù)管理器及事務(wù)控制的API | |
Spring 事務(wù)的相關(guān)配置、傳播行為、隔離級別及注解配置聲明式事務(wù) |
到了這里,關(guān)于注解、原生Spring、SchemaBased三種方式實現(xiàn)AOP【附詳細(xì)案例】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!