一、AOP背景
- aop(aspect oriented progrmming), 面向切面编程. 在oop的概念中, 开发者可以自由的定义纵向关系, 但对横向的关系却有点束手无策. Aop技术的出现可以解决这一问题.
- 进一步描述问题:
代码混乱: 越来越多的非业务需求(日志和验证等)加入后, 原有的业务方法急剧膨胀, 每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点.
代码分散: 以日志需求为例, 只是为了满足这个单一的需求, 就不得不在多个模块(方法)里多次重复相同的日志代码.如果日志需求发生变化,必须更改所有的模块.
- aop的主要编程对象是切面,而切面模块化横切关注点.
- 在应用aop编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里,以什么方式应用, 并且不必修改受影响的类
- aop的好处:
每个事物逻辑位于一个位置, 代码不分散, 便于维护和升级
业务模块更简洁, 只包含核心业务代码
二、AOP基本概念
- 切面(Aspect): 横切关注点, 跨越应用程序多个模块的功能, 被模块化的特殊对象
- 通知(Advice): 切面必须要完成的工作
- 目标(Target): 被通知的对象
- 代理: 向目标对象应用通知之后创建的对象
- 连接点(JoinPoint): 程序执行的某个特定位置. 连接点由两个信息确定: 方法表示的程序执行点; 相对点表示的方位.
- 切点(Pointcut): 每个类都有多个连接点,即需要做日志的方法. AOP通过切点定位到特定的连接点,
三、代码展示:
- 首先定义一个接口
public interface ArithmeticCalculator { int add (int a,int b); int sub (int a,int b); int mul (int a,int b); int div (int a,int b); }
- 接着定义一个实现类
public class ArithmeticCalculatorImpl implements ArithmeticCalculator{ @Override public int add(int a, int b) { return a+b; } @Override public int sub(int a, int b) { return a-b; } @Override public int mul(int a, int b) { return a*b; } @Override public int div(int a, int b) { return a/b; } }
- 定义配置文件applicationContext.xml,配置文件中需要配置两个,一个是切面的配置(哪些方法需要被切入),另一个是横切关注点
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <bean id="arithmeticCaculator" class="com.spring.aop.xml.ArithmeticCalculatorImpl"></bean> <bean id="loggingAspect" class="com.spring.aop.xml.LogingAspect"></bean> <!-- 配置 AOP --> <aop:config> <!-- 切点,每个类拥有多个连接点 --> <aop:pointcut expression="execution(* com.spring.aop.xml.ArithmeticCalculator.*(int, int))" id="pointcut"/> <!-- 切面,横切关注点 --> <aop:aspect ref="loggingAspect"> <aop:before method="beforeMethod" pointcut-ref="pointcut"/> <aop:after method="afterMethod" pointcut-ref="pointcut"/> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/> <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/> </aop:aspect> </aop:config> </beans>
- 测试
The method add begin with [1, 3] The method add ends The method add ends with 4 result: 4
5. 此外,我们在配置文件中可以配置多个横切关注点, 并注明其优先级
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <bean id="arithmeticCaculator" class="com.spring.aop.xml.ArithmeticCalculatorImpl"></bean> <bean id="loggingAspect" class="com.spring.aop.xml.LogingAspect"></bean> <!-- <bean id="timeHandler" class="com.spring.aop.xml.TimeHandler"></bean> --> <!-- 配置 AOP --> <aop:config> <!-- 切点,每个类拥有多个连接点 --> <aop:pointcut expression="execution(* com.spring.aop.xml.ArithmeticCalculator.*(int, int))" id="pointcut"/> <!-- 切面,横切关注点 --> <aop:aspect ref="loggingAspect" order="2"> <aop:before method="beforeMethod" pointcut-ref="pointcut"/> <aop:after method="afterMethod" pointcut-ref="pointcut"/> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/> <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/> </aop:aspect> <aop:aspect ref="timeHandler" order="1"> <aop:before method="printTime" pointcut-ref="pointcut"/> <aop:after method="printTime" pointcut-ref="pointcut"/> <aop:after-throwing method="printTime" pointcut-ref="pointcut" throwing="e"/> <aop:after-returning method="printTime" pointcut-ref="pointcut" returning="result"/> </aop:aspect> </aop:config> </beans>
测试:
CurrentTime is: Mon Jul 24 14:03:38 CST 2017 The method add begin with [1, 3] The method add ends The method add ends with 4 CurrentTime is: Mon Jul 24 14:03:38 CST 2017 CurrentTime is: Mon Jul 24 14:03:38 CST 2017 result: 4
来源:https://www.cnblogs.com/lfdingye/p/7228640.html