AOP是什么?
Aspect Oriented Programming,即面向切面编程。
AOP把软件系统分为两个部分:核心关注点和横切关注点。
业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。
横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事务。
AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。
一些伪代码
public class AccountServiceImpl implements IAccountService{ public void transfer(BigDecimal value){ try{ // 开启事务 // 转账操作 // 提交事务 }catch(Exception e){ // 回滚事务 }finally{ // 关闭资源 } } }
其中转账操作就可以视为核心关注点,事务相关的、关闭资源操作就可以视为横切关注点。
· AOP的目的
AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,
便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
· AOP的实现
Spring的AOP使用了动态代理实现。
如果一个类实现了接口,那么spring就使用JDK的动态代理完成AOP;
如果一个类没有实现接口,那么spring就使用cglib完成AOP。
· 一些概念
Aspect
切面。对横切关注点的抽象。
做什么增强?
日志?事务?权限认证?what?
Pointcut
切入点。
在哪里切入?
哪些类?哪些方法?where?
Adivice
增强,通知。
在什么时候切入?
方法前?方法后?方法前后?when?
Weaving
织入。把切面加入到对象,并创建出代理对象的过程。
该过程由Spring来完成。
AOP的使用
· 切入点语法
AspectJ语言,由AOP联盟制定规范。
语法 :execution(<修饰符>? <返回类型> <声明类型>? <方法名>(<参数>) <异常>?)
如execution(* com.hanaii.pss.service.*Service.*(..))表示:
插入点为com.hanaii.pss.service包下,以Service结尾的类的方法。
· 依赖的jar包
spring-aop-*.jar
com.springsource.org.aopalliance-*.jar
com.springsource.org.aspectj.weaver-*.jar
· 命名空间的配置
· xml配置
对下例配置文件进行解释:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!-- 配置bean -->
<bean id="accountService" class="com.hanaii.aop.AccountServiceImpl"/>
<bean id="txManager" class="com.hanaii.aop.TransactionManager"/>
<!-- aop相关配置 -->
<aop:config>
<!-- what: 做什么增强 -->
<aop:aspect ref="txManager" >
<!-- where: 在哪里增强 -->
<aop:pointcut expression="execution(* com.hanaii.aop.*Service.*(..))" id="txPointcut"/>
<!-- when: 什么时候增强 -->
<aop:before method="begin" pointcut-ref="txPointcut"/>
<aop:after-returning method="commit" pointcut-ref="txPointcut"/>
<aop:after-throwing method="rollback" pointcut-ref="txPointcut"/>
</aop:aspect>
</aop:config>
</beans>
<aop:config>
在该标签中,进行aop相关的配置
<aop:aspect>
配置切面。
其ref属性值为增强类的bean id。
在该标签中,对该增强类进行Pointcut和Advice的配置
<aop:pointcut>
配置切入点。
其expression属性值为切入点位置(AspectJ语言)。id属性值为该切入点的id。
Advice配置相关
增强的类型
配置相关部分标签如上文配置文件。
其pointcut-ref属性值为切入点id。
· 增强类型之环绕增强 Around Advice
最强大的一种增强类型。
环绕增强可以在方法调用前后完成自定义的行为。
环绕通知有两个要求:
1、方法必须要返回一个Object(返回的结果)
2、方法的第一个参数必须是ProceedingJoinPoint(可以继续向下传递的切入点)
ProceedingJoinPoint接口继承于JoinPoint接口
其proceed方法的作用是让目标方法执行。
JoinPoint
连接点
每个方法的前、后(两者都有也行),或抛出异常是时都可以是连接点。
spring只支持方法连接点。其他如AspectJ还可以让你在构造器或属性注入时都行。
我们在想做增强的连接点,就是切入点(Ponitcut)。
Spring AOP那些学术概念—通知、增强处理连接点(JoinPoint)切面(Aspect)