Spring AOP
AOP是OOP的延续。AOP,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是面向切面编程,使用动态代理技术,实现在不修改java源代码的情况下,运行时实现方法功能的增强。
常用术语:
#Joinpoint(连接点):
在spring中,连接点指的都是方法(指的是那些要被增强功能的候选方法)
#Pointcut(切入点):
在运行时已经被spring 的AOP实现了增强的方法
#Advice(通知):
通知指的是拦截到Joinpoint之后要做的事情。即增强的功能
通知类型:前置通知、后置通知、异常通知、最终通知、环绕通知
#Target(目标对象):
被代理的对象。比如动态代理案例中的演员
#Proxy(代理):
一个类被AOP织入增强后,即产生一个结果代理类。比如动态代理案例中的经纪人
#Weaving(织入):
织入指的是把增强用于目标对象。创建代理对象的过程
#Aspect(切面):
切面指的是切入点和通知的结合
项目中配置AOP的步骤:
pom.xml添加依赖:
spring ioc依赖
spring aspects依赖
aopalliance依赖
配置文件:
第一步:通过aop:config声明aop配置
<aop:config>
</aop:config>
第二步:通过aop:aspect配置切面
//说明:
//id:给切面取一个唯一标识的名称
//ref:指定通知对象的引用。这里是日志通知bean的id
<aop:config>
<aop:aspect id="logAspect" ref="logAdvice">
</aop:aspect>
</aop:config>
第三步:通过aop:before配置前置通知
<!--第一步:通过aop:config声明aop配置-->
<aop:config>
<!--第二步:通过aop:aspect配置切面,说明:
id:给切面取一个唯一标识的名称
ref:指定通知对象的引用。这里是日志通知bean的id
-->
<aop:aspect id="logAspect" ref="logAdvice">
<!--第三步:通过aop:before配置前置通知,说明:
method:指定通知方法的名称
pointcut-ref:指定切入点表达式的id
-->
<aop:before method="printLog" pointcut-ref="pt1"></aop:before>
</aop:aspect>
</aop:config>
第四步:通过aop:pointcut配置切入点表达式
<!--第一步:通过aop:config声明aop配置-->
<aop:config>
<!--第二步:通过aop:aspect配置切面,说明:
id:给切面取一个唯一标识的名称
ref:指定通知对象的引用。这里是日志通知bean的id
-->
<aop:aspect id="logAspect" ref="logAdvice">
<!--第三步:通过aop:before配置前置通知,说明:
method:指定通知方法的名称
pointcut-ref:指定切入点表达式的id
-->
<aop:before method="printLog" pointcut-ref="pt1"></aop:before>
<!--第四步:通过aop:pointcut配置切入点表达式,说明:
id:给切入点表达式取一个唯一标识名称
expression:指定切入点表达式
表达式组成:访问修饰符 返回值 包名称 类名称 方法名称 (参数列表)
-->
<aop:pointcut id="pt1"
expression="execution(访问修饰符 返回值 包名称 类名称 方法名称 (参数列表))">
</aop:pointcut>
</aop:aspect>
</aop:config>
<!--切入点表达式演化,说明:
全匹配方式:
修饰符 返回值 包名1 包名2 包名3 包名4(有多少个包就写多少个)类名 方法名()
public void baoming1.baoming2.baoming3.baoming4.leiming.fangfaming()
访问修饰符可以省略:
void baoming1.baoming2.baoming3.baoming4.leiming.fangfaming()
方法返回值可以使用通配符*:
* baoming1.baoming2.baoming3.baoming4.leiming.fangfaming()
包名称可以使用通配符*(有多少级包,需要多少个*):
* *.*.*.*.leiming.fangfaming()
包名称可以使用..(表示当前包和子包):
* *..leiming.fangfaming()
类名称可以使用通配符*:
* *..*.fangfaming()
方法名称可以使用通配符*:
* *..*.*()
参数列表可以使用通配符*(此时必须要有参数) :
* *..*.*(*)
参数列表可以使用..(有无参数均可):
* *..*.*(..)
-->