基于xml的AOP开发
XML配置AOP详解
切点表达式的写法
通知/(增强)的类型
前后置增强
环绕增强
异常抛出增强
最终增强
切点表达式的抽取
知识要点
①导入AOP相关坐标
②创建目标接口和目标类(内部有切点)
③创建切面类(内部有增强方法)
④将目标类和切面类的对象创建权交给spring
⑤在applicationContext.xml中配置织入关系
⑥测试代码
1、导入坐标
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
spring-context本身有aop的实现,但是aspectj更好,aspectj本身就是一个小框架。
MyAspect切面类(有增强方法)
package aop;
public class MyAspect {
public void before(){
System.out.println("前置增强....");
}
}
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.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!-- 目标对象-->
<bean id="target" class="aop.Target"></bean>
<!-- 切面对象-->
<bean id="myAspect" class="aop.MyAspect"></bean>
<!--配置织入 告诉spring框架,哪些方法(切点)需要进行哪些增强(前置、后置...)引入aop命名空间-->
<aop:config>
<!-- 声明切面-->
<aop:aspect ref="myAspect">
<!--切面:切点+通知 -->
<aop:before method="before" pointcut="execution(public void aop.Target.save())"/>
</aop:aspect>
</aop:config>
</beans>
AopTest测试类下
package aop;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
@Autowired
private TargetInterface target;
@Test
public void test1(){
target.save();
}
}
运行之后报错了
仔细一看需要Junit4.12以上的版本,改完之后,
表达式语法:
execution(修饰符] 返回值类型 包名.类名.方法名(参数))
例如
通知的配置语法:
<aop:通知类型 method="切面类中的方法名" pointcut="切点表达式"/>
<!--配置织入 告诉spring框架,哪些方法(切点)需要进行哪些增强(前置、后置...)引入aop命名空间-->
<aop:config>
<!-- 声明切面-->
<aop:aspect ref="myAspect">
<!--切面:切点+通知 -->
<aop:before method="before" pointcut="execution(public void aop.Target.save())"/>
<aop:after-returning method="afterReturn" pointcut="execution(public void aop.Target.save())"/>
</aop:aspect>
</aop:config>
写下前后置增强
public class MyAspect {
public void before(){
System.out.println("前置增强....");
}
public void afterReturn(){
System.out.println("后置增强....");
}
}
运行之后
切面类中的方法
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspect
//ProceedingJoinPoint:正在执行的连接点===切点
public Object around(ProceedingJoinPoint point) throws Throwable {
System.out.println("环绕前增强...");
Object proceed=point.proceed();//切点方法
System.out.println("环绕后增强...");
return proceed;
}
}
applicationContext.xml下
<aop:config>
<!-- 声明切面-->
<aop:aspect ref="myAspect">
<!--切面:切点+通知 -->
<aop:around method="around" pointcut="execution(public void aop.Target.save())"/>
</aop:aspect>
</aop:config>
</beans>
运行结果
切面类下
public void afterThrows(){
System.out.println("异常抛出增强");
}
目标类中需要手动加一个异常
public class Target implements TargetInterface {
@Override
public void save() {
System.out.println("save running。。。");
int i=1/0;
}
}
applicationContext.xml中
<!--配置织入 告诉spring框架,哪些方法(切点)需要进行哪些增强(前置、后置...)引入aop命名空间-->
<aop:config>
<!-- 声明切面-->
<aop:aspect ref="myAspect">
<!--切面:切点+通知 -->
<aop:after-throwing method="afterThrows" pointcut="execution(public void aop.Target.save())"/>
</aop:aspect>
</aop:config>
最终增强即为无论抛不抛出异常,这个方法都会被执行
public void after(){
System.out.println("最终增强...");
}
<aop:config>
<!-- 声明切面-->
<aop:aspect ref="myAspect">
<!--切面:切点+通知 -->
<aop:after-throwing method="afterThrows" pointcut="execution(public void aop.Target.save())"/>
<aop:after method="after" pointcut="execution(public void aop.Target.save())"/>
</aop:aspect>
</aop:config>
运行结果
当多个增强的切点表达式相同时,可以将切点表达式进行抽取,在增强中使用pointcut-ref属性代替pointcut属性来引用抽取后的切点表达式。
<aop:pointcut id="myPointcut" expression="execution(public void aop.Target.save())"/>
applicationContext.xml中
<!--配置织入 告诉spring框架,哪些方法(切点)需要进行哪些增强(前置、后置...)引入aop命名空间-->
<aop:config>
<!-- 抽取切点表达式 -->
<aop:pointcut id="myPointcut" expression="execution(public void aop.Target.save())"/>
<!-- 声明切面-->
<aop:aspect ref="myAspect">
<!--切面:切点+通知 -->
<aop:around method="around" pointcut-ref="myPointcut"/>
<aop:after-returning method="after" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
运行结果
aop织入
通知的类型:前置通知、后置通知、环绕通知、异常抛出通知、最终通知
点表达式的写法
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_60719453/article/details/126283558
内容来源于网络,如有侵权,请联系作者删除!