先复习上一篇博客:
Spring中AOP相关的基础知识
https://blog.csdn.net/JJ_Notebook/article/details/106057865
pom配置文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mj</groupId>
<artifactId>day03_02xml_aop</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- AspectJ 切入点表达式 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.13</source>
<target>1.13</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
目标对象:被代理对象
package com.mj.service;
//被代理对象(目标对象)
public class Target implements TargetInterface {
//其方法都为连接点
public void method1(){
System.out.println("目标对象的方法1被执行啦");
// int i=1/0;
}
public void method2(int i){
System.out.println(i+" :目标对象的方法2被执行啦");
}
public void method3(int i,int j){
System.out.println("有两个参数"+i+" "+j+" 的目标对象方法3被执行啦");
}
public int method4(){
int i=0;
return i;
}
}
通知类
通知类负责管理公共代码,用于对切入点进行增强
package com.mj.util;
import org.aspectj.lang.ProceedingJoinPoint;
public class Advice {
public void beforeAdvice() {
System.out.println("前置通知");
}
public void afterAdvice(){
System.out.println("后置通知");
}
public void throwAdvice(){
System.out.println("异常通知");
}
public void finallyAdvice(){
System.out.println("最终通知");
}
public void aroundAdvice(ProceedingJoinPoint pjp) {
try {
Object[] arg = pjp.getArgs();
pjp.proceed(arg);
System.out.println("环绕通知");
}catch (Throwable e){
throw new RuntimeException(e);
}finally {
}
}
}
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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置目标对象 -->
<bean id="target" class="com.mj.service.Target" ></bean>
<!--
1、把通知Bean也交给spring来管理
2、使用aop: config标签表明开始AOP的配置
3、使用aop: aspect标签表明配置切面
id属性:是给切面提供一个唯一标识
ref属性:是指定通知类bean的Id
4、在aop: aspect标签的内部使用对应标签来配置通知的类型
aop: before:表示配置前置通知
method属性:用于指定Advice类中哪个方法是前置通知
pointcut属性:用干指定切入点表达式,该表达式的含义是指对目标对象的哪些方法增强
切入点表达式的写法:
关键字:execution(表达式)
表达式:访问权限修饰符 返回类型 全类名.方法名称(参数列表)
标准写法:public void com.mj.service.Target.method1()
全通配写法:* *..*.*(..)
细节:1. 访问权限修饰符可以省略,即public void com.mj.service.Target.method1()==void com.mj.service.Target.method1()
2. 返回类型可以用通配符*替代,即 * com.mj.service.Target.method1()
3. *..表示当前包及其子包,即 * *..Target.method1()
4. 类名和方法名可以用通配符替换,即 * *..*.*()
5. ..表示多参或者无参,一个通配符*可以表示一个参数
-->
<!--配置通知Bean-->
<bean id="advice" class="com.mj.util.Advice"></bean>
<!--配置AOP-->
<aop:config proxy-target-class="true">
<!--配置切面-->
<aop:aspect id="myAdvice" ref="advice">
<!-- 前置通知-->
<aop:before method="beforeAdvice" pointcut="execution(* *..*.*(..))"></aop:before>
<!--后置通知-->
<aop:after-returning method="afterAdvice" pointcut="execution(* *..*.*(..))"></aop:after-returning>
<!--异常通知-->
<aop:after-throwing method="throwAdvice" pointcut="execution(* *..*.*(..))"></aop:after-throwing>
<!--最终通知-->
<aop:after method="finallyAdvice" pointcut-ref="ptc"></aop:after>
<!--配置切面的另一种方式-->
<!-- 利用aop:pointcut标签配置切入点表达式:
此标签写在切面配置标签aop:aspect内部时,作用范围为当前切面
此标签写在切面配置标签aop:aspect外部时,作用范围为所有切面,但需放在aop:aspect之前-->
<aop:pointcut id="ptc" expression="execution(* *..*.*(..))"></aop:pointcut>
<aop:around method="aroundAdvice" pointcut-ref="ptc"></aop:around>
</aop:aspect>
</aop:config>
</beans>
测试代码
import com.mj.service.Target;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopTest {
public static void main(String[] args) {
ApplicationContext ac= new ClassPathXmlApplicationContext("aop.xml");
Target t= (Target) ac.getBean("target");
t.method1();
t.method2(666);
t.method3(3,3);
}
}