spring 提供了 2 种 AOP 实现方式:(1)Schema-based ,(2)AspectJ
Schema-based:每个通知都需要实现接口或类,配置 spring 配置文件时在<aop:config>配置
AspectJ:每个通知不需要实现接口或类,配置 spring 配置文件是在<aop:config>的子标签<aop:aspect>中配置
基于Schema-based实现的入门程序
(1)第一步:导入jar包,除了spring中必须的包,下面两个包
(2)第二步:新建通知类
如果要实现前置通知,后置通知,在Schema-based方式中需要实现 MethodBeforeAdvice与 AfterReturningAdvice两个接口,代码如下;
前置通知代码,before方法的参数:
arg0: 切点方法对象 Method 对象
arg1: 切点方法参数
arg2:切点在哪个对象中
import java.lang.reflect.Method; import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.MethodBeforeAdvice; public class MyBeforeAdvice implements MethodBeforeAdvice{ @Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("前置通知"); } }
后置通知代码:
afterReturning方法的参数:
arg0: 切点方法返回值
arg1:切点方法对象
arg2:切点方法参数
arg3:切点方法所在类的对象
package com.airplan.pojo; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class MyAfterAdvice implements AfterReturningAdvice{ @Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
System.out.println("后置通知"); } }
第三步:aop配置
3.1 引入 aop 命名空间
3.2 配置通知类的<bean>
3.3 配置切面
3.4 * 通配符,匹配任意方法名,任意类名,任意一级包名
3.5 如果希望匹配任意方法参数 (..)
代表把返回值为任意类型,
且在PointCutClass类下面的,参数为任意的方法声明为切点
expression="* execution(void com.airplan.pojo.PointCutClass.*(..))" 下面的配置代表把通知和切入点进行对应
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="mypoint"/>
<aop:advisor advice-ref="afterAdvice" pointcut-ref="mypoint"/>
<?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-4.1.xsd "> <!-- 配置通知所在的类 -->
<bean id="beforeAdvice" class="com.airplan.pojo.MyBeforeAdvice"></bean>
<bean id="afterAdvice" class="com.airplan.pojo.MyAfterAdvice"></bean> <!-- 配置切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut expression="execution(void com.airplan.pojo.PointCutClass.testFun())" id="mypoint"/>
<!-- 配置通知 -->
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="mypoint"/>
<aop:advisor advice-ref="afterAdvice" pointcut-ref="mypoint"/> </aop:config>
<!-- 配置切点所在的类 -->
<bean id="pointCutClass" class="com.airplan.pojo.PointCutClass"></bean> </beans>
第四步:测试代码
package com.airplan.test; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.airplan.pojo.PointCutClass; public class AopDemo {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
PointCutClass pointCutClass = ac.getBean("pointCutClass",PointCutClass.class);
pointCutClass.testFun();
}
}
运行结果;