结合代码彻底理解Spring AOP的术语
每本Spring的书在介绍AOP之前,总能有一箩筐的术语,看半天似懂非懂,也就没兴趣再继续学习下去,其实并没有这么复杂。
难懂的定义我们就不贴了,就说说咱们通俗的解释,下面让我们结合代码来理清楚各个术语的含义
一、Advice(通知,叫增强更贴切低啊,也更好理解)
增强可以这么理解:为某些方法增加某些功能,这些功能可以安全、事物、日志等;
增强分为前置增强(Before Advice):对方法执行前进行的增强
后置增强(After Advice):对方法执行后进行的增强
环绕增强(Around Advice):可以理解为前置增强跟后置增强的合体
抛出增强(Throw Advice):方法抛出异常后退出执行的增强
引入增强(Introduction Advice):动态的让被增强的类实现一个接口
代码伺候:
先看前置增强、后置增强以及环绕增强,下面是jdk动态代理的代理类
package com.bckj.proxy.jdk;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class Invo implements InvocationHandler {private Object target;public Invo(Object target) {this.target = target;}@Overridepublic Object invoke(Object o, Method method, Object[] args) throws Throwable {before();Object result = method.invoke(target, args);after();return result;}private void before(){System.out.println("------method start------");}private void after(){System.out.println("------method end------");}}
上面例子中的invoke方法中before方法就叫前置加强,像after这样的方法就叫后置加强,before跟after兼具就叫环绕加强,下面看Spring Aop的代码
接口:
package test;/*** Created by DoodleJump on 2017/5/16.*/
public interface Greeting {void sayHello(String name);
}
实现类:
package test;import org.springframework.stereotype.Component;/*** Created by DoodleJump on 2017/5/16.*/
@Component
public class GreetingImpl implements Greeting {@Overridepublic void sayHello(String name) {System.out.println("Hello! "+name);}
}
前置增强类(实现org.springframework.aop.MethodBeforeAdvice接口):
package test;import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/*** 前置增强*/
@Component
public class GreetingBeforeAdvice implements MethodBeforeAdvice{@Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {System.out.println(method.getName()+" start!");}
}
后置增强类(实现org.springframework.aop.AfterReturningAdvice接口):
package test;import org.springframework.aop.AfterReturningAdvice;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/*** 后置增强*/
@Component
public class GreetingAfterAdvice implements AfterReturningAdvice {@Overridepublic void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {System.out.println(method.getName()+" end!");}
}
环绕增强类(实现org.aopalliance.intercept.MethodInterceptor接口):
package test;import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.stereotype.Component;
/*** 环绕增强*/
@Component
public class GreetingAroundAdvice implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation methodInvocation) throws Throwable {before(methodInvocation);Object result = methodInvocation.proceed();after(methodInvocation);return result;}private void before(MethodInvocation methodInvocation){System.out.println(methodInvocation.getMethod().getName()+" start!");}private void after(MethodInvocation methodInvocation){System.out.println(methodInvocation.getMethod().getName()+" end!");}
}
就以环绕增强类为例,spring配置文件的配置如下
<context:component-scan base-package="test" /><bean id="greetingProxy" class="org.springframework.aop.framework.ProxyFactoryBean"><!--需要代理的接口--><property name="proxyInterfaces" value="test.Greeting"/><!--接口实现类--><property name="target" ref="greetingImpl"/><!--拦截器名称(也就是增强类名称)--><property name="interceptorNames"><list><value>greetingAroundAdvice</value></list></property></bean>
测试类:
package test;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*** Created by DoodleJump on 2017/5/16.*/
public class Client {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring/ApplicationContext.xml");Greeting greeting = (Greeting)context.getBean("greetingProxy");greeting.sayHello("Jack");}
}
测试结果:
下面来看抛出增强:
抛出增强类(实现org.springframe.aop.ThrowAdvice接口,该接口仅仅为标识接口,没有抽象方法,但是实现类必须得有afterThrowing这个方法,不然spring在反射的时候会抛出java.lang.IllegalArgumentException: At least one handler method must be found in class [class test.GreetingThrowAdvice] 这个异常)
package test;import org.springframework.aop.ThrowsAdvice;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/*** Created by DoodleJump on 2017/5/16.*/
@Component
public class GreetingThrowAdvice implements ThrowsAdvice {public void afterThrowing(Method method,Object[] args,Object target,Exception e){System.out.println("----------Throw Exception----------");System.out.println("Target Class: "+target.getClass().getName());System.out.println("Method Name: "+method.getName());System.out.println("Exception Message: "+e.getMessage());System.out.println("-----------------------------------");}
}
让实现类的方法抛出一个异常:
@Component
public class GreetingImpl implements Greeting {@Overridepublic void sayHello(String name) {System.out.println("Hello! "+name);throw new RuntimeException("Error");}
}
配置文件的话就把增强类名称改为greetingThrowAdvice,测试类不变,测试结果:
引入增强:
动态实现的接口:
package test;/*** Created by DoodleJump on 2017/5/16.*/
public interface Apology {void saySorry(String name);
}
引入增强类(继承org.springframework.aop.support.DelegationIntroductionInterceptor并实现动态接口):
package test;import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
import org.springframework.stereotype.Component;/*** Created by DoodleJump on 2017/5/16.*/
@Component
public class GreetingIntroAdvice extends DelegatingIntroductionInterceptor implements Apology {@Overridepublic void saySorry(String name) {System.out.println("Sorry! "+name);}@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {return super.invoke(invocation);}
}
spring配置文件:
<bean id="greetingProxy" class="org.springframework.aop.framework.ProxyFactoryBean"><!--需要代理的接口--><property name="proxyInterfaces" value="test.Apology"/><!--接口实现类--><property name="target" ref="greetingImpl"/><!--拦截器名称(也就是增强类名称)--><property name="interceptorNames"><list><value>greetingIntroAdvice</value></list></property><!--代理目标类(false:jdk代理,true:cglib代理)--><property name="proxyTargetClass" value="true"/></bean>
测试类:
package test;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*** Created by DoodleJump on 2017/5/16.*/
public class Client {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring/ApplicationContext.xml");GreetingImpl greetingImpl = (GreetingImpl)context.getBean("greetingProxy");greetingImpl.sayHello("Jack");Apology apology = (Apology) greetingImpl;apology.saySorry("Jack");}
}
测试结果:
可以看到生成的代理类动态的实现了Apology这个接口。
二、Weaving(织入):对方法的增强,比如上面所说的前置增强、后置增强以及环绕增强都是织入的表现
根据不同的实现技术,AOP有三种织入的方式:
a、编译期织入,这要求使用特殊的Java编译器。
b、类装载期织入,这要求使用特殊的类装载器。
c、动态代理织入,在运行期为目标类添加增强生成子类的方式。
Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。
三、Introduction(引入):对类的增强,比如上面所说的引入增强
四、Pointcut(切点):切入的连接点,即织入或引入发生的那个方法或类
五、Aspect(切面):增强+切点,配置如下
六、Join Point(连接点):所有可以切入的点,切点只是你选择的部分连接点
结合代码彻底理解Spring AOP的术语相关推荐
- 从面向对象设计思想出发理解Spring AOP编程
都说AOP是OOP(面向对象)的继承与延续,我觉得理解AOP还是得从OOP出发,经历从暴露问题到解决问题的过程. 目录 一. 面向对象设计思想(OOP) (1)概述 1. POP编程 2. OOP的优 ...
- 如何理解 Spring AOP 以及使用 AspectJ?
作者 | 阿文 责编 | 屠敏 出品 | CSDN(ID:CSDNnews) 在 Spring 中 AOP 是一个非常非常重要的概念,那么什么是AOP呢? AOP 即面向切面编程,也可以叫做面向方向编 ...
- 彻底理解Spring AOP
目录 前言 1. AOP概念 2. AOP的实现 3. Spring的IoC理解: 4. Sping知识整理 前言 AOP英文名为Aspect Oriented Programming,意为面向切面编 ...
- Spring AOP相关术语解释及简单使用
什么是面向切面编程 百度百科定义为:在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. ...
- 带你理解Spring AOP
AOP概述 在我们的日常开发中,除了正常业务逻辑外,还可能经常会需要在业务逻辑的特定位置加入日志,以便于调试和问题分析.但是这种插入日志的逻辑和业务逻辑间并不存在连续性和依赖性,这种逻辑侵入随着项目的 ...
- 深入理解Spring AOP思想
什么是AOP?AOP解决了什么问题? 在传统的开发模式中,以下层次的是非常常见的一种,业务层每一个方法都要有重复的事务代码 如何改善这个问题? AOP希望将A.B 这些分散在各个业务逻辑中的相同代码, ...
- 正确理解Spring AOP中的Around advice
Spring AOP中,有Before advice和After advice,这两个advice从字面上就可以很容易理解,但是Around advice就有点麻烦了. 乍一看好像是Before ad ...
- java @around_正确理解Spring AOP中的Around advice
Spring AOP中,有Before advice和After advice,这两个advice从字面上就可以很容易理解,但是Around advice就有点麻烦了. 乍一看好像是Before ad ...
- Spring AOP的术语:
Aspect: 切面,由一系列切点.增强和引入组成的模块对象,可定义优先级,从而影响增强和引入的执行顺序.事务管理(Transaction management)在java企业应用中就是一个很好的切面 ...
最新文章
- Android 学习视频
- Spring boot切换Servlet容器
- python调用zabbixapi接口_python调用zabbix api获取主机信息
- Unity 实现物体破碎效果(转)
- Python pandas库159个常用方法使用说明(转载)
- Toastr.js插件用法
- Eclipse javax.servlet.jsp.PageContext cannot be resolved to a type 错误解决办法
- python psutil 进行系统管理 no.2
- 我经常逛的技术网站,个个经典
- 一个简单的通用序列数据结构
- OpenGL(一)二维图形的绘制:一个简单的绘制矩形程序
- 手机CAD如何快速看图下载?
- A股管家股票自动交易软件系统,功能完善强大
- SPSS-非参数检验
- 油猴Safari插件Tampermonkey
- PicPick滚屏截图
- Unet分割直肠肿瘤图像
- 纸上得来终觉浅(c语言小知识总结)
- Arrays.asList()
- 莫烦强化学习笔记整理(九)DDPG
热门文章
- 如何在dynamo中使用Python编程
- 计算机基础之网络层的功能和服务
- C语言没有string类型
- mysql中最常用到的数据类型,约束条件,以及表,字段,行的crud操作指令,function和precedure之间的区别,索引,安全,事务...
- 获得CCNA和CCNP及CCIE认证的必备条件和有效期绍
- index.php catid 什么程序,br/br/br/这段PHP代码是用什么加密的呢?怎? 爱问知识人...
- Win10 由于安装软件造成的开机蓝屏解决方法
- windows10关闭安全中心服务器,微软:Windows 安全中心问题阻止 Win10 版本 2004 更新...
- VM15安装Linux (红帽Linux)
- 手把手教你 Tableau 绘制堆积柱状图(二)