Spring Aop详解

扶醉桌前 提交于 2020-02-29 16:40:27
一、AOP背景
  • aop(aspect oriented progrmming), 面向切面编程. 在oop的概念中, 开发者可以自由的定义纵向关系, 但对横向的关系却有点束手无策. Aop技术的出现可以解决这一问题.
  • 进一步描述问题: 
            代码混乱: 越来越多的非业务需求(日志和验证等)加入后, 原有的业务方法急剧膨胀, 每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点.
            代码分散: 以日志需求为例, 只是为了满足这个单一的需求, 就不得不在多个模块(方法)里多次重复相同的日志代码.如果日志需求发生变化,必须更改所有的模块.
  • aop的主要编程对象是切面,而切面模块化横切关注点.
  • 在应用aop编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里,以什么方式应用, 并且不必修改受影响的类
  • aop的好处:
            每个事物逻辑位于一个位置, 代码不分散, 便于维护和升级
            业务模块更简洁, 只包含核心业务代码
二、AOP基本概念
  • 切面(Aspect): 横切关注点, 跨越应用程序多个模块的功能, 被模块化的特殊对象
  • 通知(Advice): 切面必须要完成的工作
  • 目标(Target): 被通知的对象
  • 代理: 向目标对象应用通知之后创建的对象
  • 连接点(JoinPoint): 程序执行的某个特定位置. 连接点由两个信息确定: 方法表示的程序执行点; 相对点表示的方位. 
  • 切点(Pointcut): 每个类都有多个连接点,即需要做日志的方法. AOP通过切点定位到特定的连接点,
三、代码展示:
  1. 首先定义一个接口
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);
 
}
  1. 接着定义一个实现类
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;
     }
 
}
  1. 定义配置文件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>
  1. 测试
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

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
          
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!