Spring中AOP原理,源码学习笔记
一.AOP(面向切面编程):通过预编译和运行期动态代理的方式在不改变代码的情况下给程序动态的添加一些功能。利用AOP可以对应用程序的各个部分进行隔离,在Spring中AOP主要用来分离业务逻辑和系统级服务。
系统级服务指的是:事务处理,日志记录,性能统计,安全控制,异常处理等,因为这些功能分散在程序的各个模块中,又是通用的,所以可以将它从业务逻辑中分离出来。
连接点(joinpoint):在连接点可以拦截方法的执行,在连接点前后织入上述的这些系统级服务(织入的就是通知)。
切入点(pointcut):连接点的集合。根据切入点表达式来确定我们将执行拦截的位置。
通知:到达连接点时执行的代码,即我们织入的功能。
以前的Spring,我们要使用AOP,在编写通知时必须实现一些接口,如:实现Before Advice时,Advice类要实现org.springframework.aop.MethodBeforeAdvice接口。
现在有另外两种方式,
(1)基于XML Schema的设置,
1. package com.savage.aop;
2.
3. import org.aspectj.lang.JoinPoint;
4.
5. public class LogBeforeAdvice {
6. public void before(JoinPoint joinPoint) {
7. System.out.println("Logging before " + joinPoint.getSignature().getName());
8. }
9. }
对应XML中的相关配置
<bean id="beforeAdvice" class="test.advice.BeforeAdvice" />
<aop-config>
<aop-aspect id="aspectOne" ref="beforeAdvice">
<aop-pointcut id="pointcutOne exepression="execution(* test.service.*.*(..))" />
<aop-before pointcut-ref="pointcutOne" method="before" /> //也可直接简写成<aop-before pointcut="execution(* test.service.*.*(..))" method="before" />,去掉<aop-pointcut />
</aop-aspect>
</aop-config>
如上,编写通知类不用实现任何接口,JoinPoint对象代表的就是当前连接点,供织入功能时使用,通过它可获得目标对象(getTarget()方法),目标方法名(getSignature().getName()),目标方法接收的实参(getArgs(),返回对象数组)等信息。
(2)注解式写法
在通知类上加注解@Aspect
通知方法上加上通知类型,共有5种通知类型:@Before,@After,@AfterReturning,@AfterThrowing,@Arround
环绕通知最强大,其方法返回类型为Object,第一个参数必须是ProceedingJoinPoint,方法抛出Throwable
http://book.51cto.com/art/200809/90712.htm
在spring配置文件中添加,
<aop:aspectj-autoproxy />
<context:component-scan base-package="studyspringframe" />
或者不通过注解@component定义bean,则
<aop:aspectj-autoproxy />
<bean class="studyspringframe.aspect.advice.AdviceDefine" />
二.关于开源连接池实现DBCP的配置
如图,DBCP连接池配置对应的是对象池GenericObjectPool的属性