一、传统的spring aop编程介绍
1、主要的五种通知:
MethodBeforeAdvice:前置通知,在目标执行之前实施增强
AfterReturningAdvice:后置通知,在目标执行之后实施增强
MethodInterceptor:环绕通知,在目标执行前后实施增强
ThrowsAdvice:异常抛出通知,在方法抛出异常后实施增强
IntroductionInterceptor:引介通知,在目标类中添加一些新的方法和属性
2、通过execution定义切点表达式
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
例如:
1、"execution(* top.einino.service.impl.PersonServiceImpl.*(..))"
表示将PersonServiceImpl类中的所有方法定义为切点
2、"execution(* top.einino.service.impl..*.*(..))"
表示impl包以及impl的所有子包的所有类的所有方法
3、"execution(* *.save*(..))"
表示以save开头的所有方法名作为切点
二、简单的例子
1、建工程,导入spring相应的包
2、写目标对象,service层
package top.einino.service;
public interface PersonService {
void eat();
}
package top.einino.service.impl;
import top.einino.service.PersonService;
public class PersonServiceImpl implements PersonService{
@Override
public void eat(){
System.out.println("吃饭!!");
}
}
3、自定义通知
a、环绕通知
package top.einino.interceptor;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
//环绕通知:在目标方法执行前后实施增强
public class PersonMethodInterceptor implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
//方法执行前
System.out.println("买菜");
Object result = methodInvocation.proceed();
//方法执行后
System.out.println("清洗");
return result;
}
}
b、前置通知
package top.einino.interceptor;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
//前置通知:在目标方法执行前实施增强
public class PersonMethodBeforeAdvice implements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] arg1, Object arg2)
throws Throwable {
System.out.println("做饭");
}
}
4、进行aop配置
<?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实例化 -->
<!-- 配置目标对象 -->
<bean id="personService" class="top.einino.service.impl.PersonServiceImpl"/>
<!-- 环绕通知 -->
<bean id="personMethodInterceptor" class="top.einino.interceptor.PersonMethodInterceptor"/>
<!-- 前置通知 -->
<bean id="personMethodBeforeAdvice" class="top.einino.interceptor.PersonMethodBeforeAdvice"/>
<!-- 进行aop相关配置 -->
<!-- proxy-target-class="true"表明使用cglib代理 -->
<aop:config proxy-target-class="true">
<!-- 定义切点,为PersonServiceImpl的所有方法 -->
<aop:pointcut expression="execution(* top.einino.service.impl.PersonServiceImpl.*(..))" id="personPointcut"/>
<!-- 定义spring传统AOP的切面的, 只支持一个PointCut和 一个Advice,定义的顺序决定了方法切入的顺序-->
<aop:advisor advice-ref="personMethodInterceptor" pointcut-ref="personPointcut"/>
<aop:advisor advice-ref="personMethodBeforeAdvice" pointcut-ref="personPointcut"/>
</aop:config>
</beans>
4、测试
package top.einino.junit;
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;
import top.einino.service.PersonService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class TestMethodInterceptor {
@Autowired
PersonService personService;
@Test
public void testEat(){
personService.eat();
}
}
三、小结
本博文首先对传统的spring aop的一些常用知识点做了下介绍,并通过一个例子深入对spring aop的理解以及明白其如何使用。
如果有疑问或者对该博文有何看法或建议或有问题的,欢迎评论,恳请指正!