springaop

63 阅读3分钟

```html


## 概念

AOP: Aspect Oriented Programming 面向方面/切面编程. 重心:切面,分析寻找共通切面

OOP: Object Oriented Programming 面向对象编程 OOAD:面向对象分析和设计(定义类及其内部属性和方法) 重心:对象,分析设计类

AOP还是OOP编程,主要目的是将共通业务逻辑跟传统业务进行拆分,然后通过配置模式将两个业务组件结合。(将共通业务和传统业务解耦),例如事务逻辑、异常处理逻辑、性能监控。

优点:在原有代码不修改情况下,追加新的功能逻辑。

![](http://i.imgur.com/7GeInQL.png)

## 应用

0. 方面/切面(Aspect,加什么功能?)

   在同一时刻、执行的共通的处理逻辑(时机+功能)。方面组件指的是封装了共通处理的组件。

1. 切入点(Pointcut,给谁加?)

   指定切入的目标组件及方法。Spring提供了多种切入点表达式

   * 方法限定表达式

   > execution(修饰符? 返回类型 方法名(参数) throws异常?)

   //匹配Spring容器中所有以save打头的方法 execution(\* save\*(..))

//匹配AddressServiceImpl组件中所有方法 execution(* cn.xdl.service.AddressServiceImpl.(..)) //匹配cn.xdl.service包下所有类所有方法 execution( cn.xdl.service..(..)) //匹配cn.xdl.service包和子包下所有类所有方法 execution(* cn.xdl.service...(..))


* 类型限定表达式

> within(包名.类型名)

//匹配AddressServiceImpl类所有方法 within(cn.xdl.service.AddressServiceImpl) //匹配cn.xdl.service包下所有类所有方法 within(cn.xdl.service.) //匹配cn.xdl.service包和子包下所有类所有方法 within(cn.xdl.service..)


* bean名称限定表达式

> bean(Spring容器中对象的id名)

//匹配id=addressService的对象所有方法 bean(addressService) //匹配id名以Service结尾的对象所有方法 bean(*Service)

可以使用&&、||、!符号将多个表达式连接使用。


3. 通知(Advice,什么时机加?)

   指定追加切面组件功能的时机。例如在目标方法之前、之后等等。Spring提供以下几种时机。try{<!-- -->

//使用环绕通知-前置逻辑aop:around //使用前置通知--aop:before //执行目标方法处理 //使用后置通知--aop:after-returning //使用环绕通知-后置逻辑


}catch(){<!-- -->

//使用异常通知--aop:after-throwing


}finally{<!-- -->

//使用最终通知--aop:after


}

## 注解配置

0. 开启组件扫描,将方面组件扫描,追加@Component标记

\<context:component-scan base-package="cn.xdl.jd.aop"/>

<!---->

2. 开启AOP注解配置,追加@Aspect、@Before、@After等标记

\<aop:aspectj-autoproxy />

## AOP案例1

需求:检测每个请求处理耗费时间。

  • 切面组件
计时,计算时间差额,在控制台打印。
  • 切入点
给所有Controller组件方法
within(cn.xdl.jd.controller.*)


前置和最终通知的方法定义规则:

public void xxx(){...}


**环绕通知方法定义规则:**

public Object xxx(ProceedingJoinPoint pjp) throws Throwable{...}


**异常通知方法定义规则:**

public void xxx(Exception e){...}


后置通知方法定义规则:

public void xxx(Object retVal){...}


## AOP案例2

需求:将请求处理中的异常信息记录到文件中。


0. 切面组件

   将异常信息写入文件,(文件位置、文件名)

1. 切入点

   作用到所有Service组件上within(cn.xdl.jd.service..\*)

2. 通知

   异常通知。[aop:after-throwing]()----\@AfterThrowing

spring-aopxml配置\


\<?xml version="1.0" encoding="UTF-8"?>\<beans xmlns="<http://www.springframework.org/schema/beans>"

xmlns:xsi="www.w3.org/2001/XMLSch…" xmlns:context="www.springframework.org/schema/cont…" xmlns:jdbc="www.springframework.org/schema/jdbc"   xmlns:jee="www.springframework.org/schema/jee" xmlns:tx="www.springframework.org/schema/tx" xmlns:aop="www.springframework.org/schema/aop" xmlns:mvc="www.springframework.org/schema/mvc" xmlns:util="www.springframework.org/schema/util" xmlns:jpa="www.springframework.org/schema/data…" xsi:schemaLocation=" www.springframework.org/schema/bean… www.springframework.org/schema/bean… www.springframework.org/schema/cont… www.springframework.org/schema/cont… www.springframework.org/schema/jdbc www.springframework.org/schema/jdbc… www.springframework.org/schema/jee www.springframework.org/schema/jee/… www.springframework.org/schema/tx www.springframework.org/schema/tx/s… www.springframework.org/schema/data… www.springframework.org/schema/data… www.springframework.org/schema/aop www.springframework.org/schema/aop/… www.springframework.org/schema/mvc www.springframework.org/schema/mvc/… www.springframework.org/schema/util www.springframework.org/schema/util…

<context:component-scan base-package="cn.xdl.jd.aop"/> ​

<aop:aspectj-autoproxy />


\</beans>

aop类的使用

@Component//扫描,等价于\<bean>定义\
@Aspect//指定为方面,等价于\<aop:aspect>\
public class LoggerBean {<!-- -->\
    \
    @Before("within(cn.xdl.jd.controller.\*)")\
    public void logController(){<!-- -->\
        System.out.println("---进入Controller方法处理---");\
    }\
    \
}\
\
\


\


\


\


\