aop各术语的通俗描述
Joinpoint连接点:调用切点函数的那一行程序就是。
Target目标对象:需要补充功能的函数体的对象。
Pointcut切点:目标对象的中的(Target)的方法名。
Advice增强方法:给目标对象中的切点加入一段程序就叫增强方法。
Aspect切面:包括切点(Pointcut)和增强(Advice)方法。
Weaving织入:将增强方法加入到目标对象(切入点)的过程就是织入。
Proxy代理:在织入未开始时也就是织入开始前,将目标对象利用动态代理也就是反射技术生成一个代理对象,以便织入可以利用动态代理将增强方法加入到目标对象中。
Introduction介入:织入的整个过程叫介入差不多我理解。
aop专业描述
Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
Target(目标对象):织入 Advice 的目标对象.。
Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程。
aop如何使用
完全可以看着这个理解aop
图片使用网上资源
使用步骤
- 编码增强类
- 加入bean
- 编写切入点
- 切入点与增强方法链接
步骤 | xml | 注解 |
---|---|---|
编码增强类 | 无 | 无 |
加入bean | <bean id=“aspect” class=“…”> | @Aspect |
编写切入点 | <aop:config><aop:pointcut id=“pointcut” expression=“execution(* *…*())”/></aop:config> | @Before(“execution(* *(…))”) |
切入点与增强方法链接 | <aop:config><aop:aspect ref=“aspect”><aop:before method=“all()” pointcut-ref=“pointcut”></aop:aspect></aop:config> | @Before(“execution(* *(…))”)public void all(){…} |
xml代码
增强方法的五种类型
先将目标对象和增强方法的对象加入bean
再定义增强方法要配置到那个切入点的规则
再声明使用那种类型的增强方法
<!-- 加入bean-->
<bean id="目标对象" class="com.hehehe.Hahaha"/>
<bean id="增强对象" class="com.hehehe.Aaaa"/>
<!-- 设置增强方法的切入规则-->
<!--aop配置-->
<aop:config>
<!--配置切面-->
<!--配置切入点可以增强那种方法 也就是 增强方法给bean里的那种方法增强-->
<aop:pointcut id="pt" expression="execution(* *..*())"/>
<!--配置切面-->
<aop:aspect ref="增强对象">
<!—通知与切入点之间的关系-->
<aop:before method="logAdvice" pointcut-ref="pt"/>
</aop:aspect>
</aop:config>
1.前置增强,在切入点方法里的第一行加入增强方法
<!-- 说明要使用那种方法加入增强方法-->
<aop:aspect ref="增强对象">
<!—通知与切入点之间的关系-->
<aop:before method="logAdvice" pointcut-ref="pt"/>
</aop:aspect>
2.后置增强,在切入点方法的结束处开始增强
<aop:aspect ref="增强对象">
<aop:after method="methodName" pointcut-ref="pt"/>
</aop:aspect>
3.环绕增强,前置增强和后置增强的结合
<aop:aspect ref="增强对象">
<aop:around method="methodName" pointcut-ref="pt"/>
</aop:aspect>
4.返回后增强,原始方法正常执行完毕并返回结果后执行
<aop:aspect ref="增强对象">
<aop:after-returning method="methodName" pointcut-ref="pt"/>
</aop:aspect>
5.抛出异常后增强,原始方法抛出异常后执行
<aop:aspect ref="增强对象">
<aop:after-throwing method="methodName" pointcut-ref="pt"/>
</aop:aspect>
增强方法获取目标函数的参数
1.使用JoinPoint获取参数
public void before(JoinPoint jp) throws Throwable {
Object[] args = jp.getArgs();
}
2 配置切入点
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pt" expression="execution(* *..*()) && args(a,b)"/>
</aop:config>
// 与切入点的参数名一样
public void before(int a,int b) throws Throwable {
Object[] args = jp.getArgs();
}
3 切入点和增强方法
<!--配置切面-->
<!--配置切入点可以增强那种方法 也就是 增强方法给bean里的那种方法增强-->
<aop:pointcut id="pt" expression="execution(* *..*()) && args(a,b)"/>
<!--配置切面-->
<aop:aspect ref="增强对象">
<!—通知与切入点之间的关系-->
<aop:before method="logAdvice" pointcut-ref="pt" arg-names="b,a"/>
</aop:aspect>
</aop:config>
// 与切入点的参数名一样
public void before(int a,int b) throws Throwable {
Object[] args = jp.getArgs();
}
切入点的配置规则
拦截规则
关键字(访问修饰符 返回值 包名.类名.方法名(参数)异常名)
execution(public int *.*.*(int a,int b) )
execution(public int *.*.*(..) )
拦截规则的作用范围
<aop:config>
<!--1配置公共切入点-->
<aop:pointcut id="pt1" expression="execution(* *(..))"/>
<aop:aspect ref="myAdvice">
<!--2配置局部切入点-->
<aop:pointcut id="pt2" expression="execution(* *(..))"/>
<!--3直接配置切入点-->
<aop:before method="logAdvice" pointcut="execution(* *(..))"/>
<!--引用公共切入点-->
<aop:before method="logAdvice" pointcut-ref="pt1"/>
<!--引用局部切入点-->
<aop:before method="logAdvice" pointcut-ref="pt2"/>
</aop:aspect>
</aop:config>
注解代码
启用增强类型注解包的扫描
先将目标对象和增强方法的对象加入bean
声名增强类
设置切入点的规则函数
设置增强方法的类型
@EnableAspectJAutoProxy
@Compaonse
@Aspect
@Before("execution(* *(..))")
public void before(){
}
aop原理
1 动态代理技术
在运行时利用动态代理技术增强目标函数
jdk proxy默认
CGLIB
2 预编译技术
在(手动写入)编译时将目标函数增强