基本概念的介绍
- 连接点(Jointpoint):在Spring中表示方法执行连接点,通俗的来说就是在哪里插入切面代码。
- 切入点(PointCut):一组连接点的集合
- 通知(Advice):在连接点上执行的行为,通知提供了AOP需要在连接点出如何扩展现有行为。包括前置通知(before advice),后置通知(after advice),环绕通知(around advice),Spring通过拦截器实现。
- 前置通知(Before Advice):在切入点选择的连接点处的方法之前执行的通知,该通知不影响正常程序执行流程(除非该通知抛出异常,该异常将中断当前方法链的执行而返回)。
- 后置返回通知(After returning Advice):在切入点选择的连接点处的方法正常执行完毕时执行的通知,必须是连接点处的方法没抛出任何异常正常返回时才调用后置通知。
- 后置异常通知(After throwing Advice): 在切入点选择的连接点处的方法抛出异常返回时执行的通知,必须是连接点处的方法抛出任何异常返回时才调用异常通知。
- 后置最终通知(After finally Advice): 在切入点选择的连接点处的方法返回时执行的通知,不管抛没抛出异常都执行,类似于Java中的finally块。
- 环绕通知(Around Advices):环绕着在切入点选择的连接点处的方法所执行的通知,环绕通知可以在方法调用之前和之后自定义任何行为,并且可以决定是否执行连接点处的方法、替换返回值、抛出异常等等。
- 切面(Aspect):连接点和通知的集合
- 目标对象(Target object):被组织的对象,即对象被代理,实现切面编程的嵌入
说了这么多概念,有点蒙圈,还是写个实例看容易看懂。
bean配置如下
<bean id ="goodsService" class="com.shinerio.service.GoodsService"> </bean>
<bean id ="logAop" class="com.shinerio.aop.LogAopUtils"/>
<aop:config>
<!-- 切入点配置,expression属性用来定义切入点模式,默认是AspectJ语法 -->
<aop:pointcut id="pointcut" expression="execution(* com.shinerio..*.*(..))" />
<aop:aspect ref="logAop"><!-- 切面配置,ref用来引入切面类 -->
<!-- before,after用来定义通知,pointcut-ref用于引用切入点bean,method用来引用通知类具体方法 -->
<aop:before pointcut-ref="pointcut" method="beforeAdvice"/>
<aop:after pointcut="execution(* com.shinerio..*.*(..))"
method="afterAdvice"/>
</aop:aspect>
</aop:config>
目标类goodsService
public class GoodsService implements GoodsServiceInterface {
public void save() {
System.out.println("doSave");
}
}
通知类
public class LogAopUtils {
public void beforeAdvice() {
System.out.println("前置通知日志记录");
}
public void afterAdvice() {
System.out.println("后置通知日志记录");
}
}
测试类
public void testGetBean() {
ApplicationContext context = new FileSystemXmlApplicationContext(
"src/applicationContext.xml");
GoodsServiceInterface service = context.getBean("goodsService",
GoodsServiceInterface.class);
service.save();
}
输出:
前置通知日志记录
doSave
后置通知日志记录
注意:这里必须通过接口来接收