二,AOP
- AOP目标
- 让我们专注于业务功能处理
- AOP原理
- 将复杂的需求分解出不同方面,将不同对象、不同模块之间的共同业务集中解决
- 通过动态代理的方式,把抽离出来的共性代码"织入"到业务代码中,实现对原有代码的增强处理
如图
- AOP相关术语
- Aspect(切面)
- Advice(增强处理)
- Pointcut(切入点)
- Join Point(连接点)
- Target Object(目标对象)
- AOP proxy(AOP 代理)
- Weaving(织入)
定义切入点
切入点:简单来说,就是连接点的查询条件
<aop:config> <aop:pointcut id="loggerPointcut" expression="execution(public void print(..))"/> <aop:aspect ref="sysLogger"> </aop:aspect> </aop:config>
表达式匹配规则举例
expression="execution(public void print(..))"/>
- 各种增强
增强类型 | 特点 |
Before | 前置增强处理,在目标方法前织入增强处理 |
AfterReturning | 后置增强处理,在目标方法正常执行(不出现异常)后织入增强处理 |
AfterThrowing | 异常增强处理,在目标方法抛出异常后织入增强处理 |
After | 最终增强处理,不论方法是否抛出异常,都会在目标方法最后织入增强处理 |
Around | 环绕增强处理,在目标方法的前后都可以织入增强处理。可以控制目标方法是否执行 |
织入增强处理
织入:在切入点插入增强处理
- 演示:创建实体类添加增强方法
package com.xinxi2.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Aspect @Component() public class LoggerAdvic { @Before("execution(public void wprk())") public void before(JoinPoint jp){ System.out.println("前缀增强"); } @AfterReturning("execution(public void wprk())") public void retuRning(JoinPoint jp){ System.out.println("后置增强"); } @AfterThrowing("execution(public void wprk())") public void afterException(JoinPoint jp){ System.out.println("异常增强"); } @Around("execution(public void wprk())") public Object around(ProceedingJoinPoint pjp){ Object result = null; try { System.out.println("--------------------"); result = pjp.proceed(); // 执行方法 System.out.println("********************"); }catch (Throwable e){ e.printStackTrace(); } System.out.println("环绕增强"); return result; } @After("execution(public void wprk())") public void after(JoinPoint jp){ System.out.println("最终增强"); } }
- 在applicationContext.xml中写aop:config标签
<aop:config> <aop:pointcut id="loggerPointcut" expression="execution(public void print(..))"/> <aop:aspect ref="sysLogger"> <aop:before method="beforeLogger" pointcut-ref="loggerPointcut"></aop:before> <aop:after-returning method="afterReturning" pointcut-ref="loggerPointcut" returning="obj"></aop:after-returning> <aop:after-throwing method="afterException" pointcut-ref="loggerPointcut" throwing="e"></aop:after-throwing> <aop:around method="around" pointcut-ref="loggerPointcut" ></aop:around> <aop:after method="after" pointcut-ref="loggerPointcut"></aop:after> </aop:aspect> </aop:config>
解释以上几种增强方法
异常抛出增强
- 特点
- 在目标对象方法抛出异常时织入增强处理
- 可灵活拔插的异常处理方案
<aop:config> <aop:pointcut id="loggerPointcut" expression="execution(public void print(..))"/> <aop:aspect ref="sysLogger"> <!-- 异常增强 --> <aop:after-throwing method="afterException" pointcut-ref="loggerPointcut" throwing="e"></aop:after-throwing> </aop:aspect> </aop:config>
最终增强
- 特点
- 无论方法正常运行还是抛出异常,都会在目标方法最后织入增强处理,即:该增强都会得到执行
- 与Java中finally代码块的作用相似,通常用于释放资源
- 可灵活拔插
<aop:config> <aop:pointcut id="loggerPointcut" expression="execution(public void print(..))"/> <aop:aspect ref="sysLogger"> <!-- 最终增强 --> <aop:after method="after" pointcut-ref="loggerPointcut"></aop:after> </aop:aspect> </aop:config>
环绕增强
- 特点
- 目标方法前后都可织入增强处理
- 可获取或修改目标方法的参数、返回值
- 可对目标方法进行异常处理,甚至可以决定目标方法是否执行
<aop:config> <aop:pointcut id="loggerPointcut" expression="execution(public void print(..))"/> <aop:aspect ref="sysLogger"> <!-- 环绕增强 --> <aop:around method="around" pointcut-ref="loggerPointcut" ></aop:around> </aop:aspect> </aop:config>
构造注入
- 可以使用带参构造
- Spring通过构造方法为属性赋值的一种注入方式
- 可以在对象初始化时对属性赋值,具有良好的时效性
<bean id="daodao" class="com.xinxi2.bean.TSysUser"> <constructor-arg name="acccunt" value="王某某"></constructor-arg> <constructor-arg name="address" value="王某"></constructor-arg> </bean>
P命名的注入
使用属性而不是子元素的形式配置Bean的属性
<bean id="唯一标识" class="类的全路径" p:"属性1"="注入的值" p:"属性2"="注入的值" /> <bean id="唯一标识" class="类的全路径" p:属性-ref="注入的Bean" />
配置文件中使用p命名空间时,需要先添加p命名空间的声明
xmlns:p=“http://www.springframework.org/schema/p”