引言
现在项目中,尤其是大的项目,业务逻辑都是相对于小型项目来讲,都是业务逻辑复杂的。比如说,咱们以前的权限系统都是实现了资源的管理或者是角色管理。现在系统加入了更多的业务逻辑条件,来让用户的选择更少,让大家用起来更方面。
于是,我们提出了立体化权限系统,通过立体化的权限系统,通过:组织机构、功能、时间、空间等都来约束,即可实现。
我们都知道,第一开始,我们所有的业务逻辑都是耦合在一起的,就算我们通过一些方式:将大对象划分多个方法,通过继承关系,通过组合等等,都不能从根本上解决业务的耦合。
Spring 就发明了AOP的功能,业务横切,也就是说,我们一些业务之间的关联,就可以通过AOP直接将业务和业务之间联系起来,再代码上不过改变,只改变配置文件,支持了热部署,并且达到了很高的代码复用率。
上代码:
项目为web项目:
添加配置文件application-config.xml:
<span style="font-size:18px;"><?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="xMLAdvice" class="com.tgb.itoo.aop.XMLAdvice" />
<aop:config>
<aop:aspect id="aspect" ref="xMLAdvice">
<aop:pointcut id="pointUserMgr" expression="execution(* com.tgb.itoo.basic.controller.*.validateBuildN*(..))"/>
<aop:before method="doBefore" pointcut-ref="pointUserMgr"/>
<aop:after method="doAfter" pointcut-ref="pointUserMgr"/>
<aop:around method="doAround" pointcut-ref="pointUserMgr"/>
<aop:after-returning method="doReturn" pointcut-ref="pointUserMgr"/>
<aop:after-throwing method="doThrowing" throwing="ex" pointcut-ref="pointUserMgr"/>
</aop:aspect>
</aop:config>
</beans></span>
XMLAdive.java:
<span style="font-size:18px;">package com.tgb.itoo.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* Advice通知类 测试after,before,around,throwing,returning Advice.
*
* @author Admin
*
*/
public class XMLAdvice {
/**
* 在核心业务执行前执行,不能阻止核心业务的调用。
*
* @param joinPoint
*/
private void doBefore(JoinPoint joinPoint) {
System.out.println("-----doBefore().invoke-----");
System.out.println(" 此处意在执行核心业务逻辑前,做一些安全性的判断等等");
System.out.println(" 可通过joinPoint来获取所需要的内容");
System.out.println("-----End of doBefore()------");
for (int i = 0; i < joinPoint.getArgs().length; i++) {
System.out.println(joinPoint.getArgs()[i]);
}
System.out.println(joinPoint.getSignature().getName());
System.out.println("=====checkSecurity====");
}
/**
* 手动控制调用核心业务逻辑,以及调用前和调用后的处理,
*
* 注意:当核心业务抛异常后,立即退出,转向After Advice 执行完毕After Advice,再转到Throwing Advice
*
* @param pjp
* @return
* @throws Throwable
*/
private Object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("-----doAround().invoke-----");
System.out.println(" 此处可以做类似于Before Advice的事情");
// 调用核心逻辑
Object retVal = pjp.proceed();
System.out.println(" 此处可以做类似于After Advice的事情");
System.out.println("-----End of doAround()------");
return retVal;
}
/**
* 核心业务逻辑退出后(包括正常执行结束和异常退出),执行此Advice
*
* @param joinPoint
*/
private void doAfter(JoinPoint joinPoint) {
System.out.println("-----doAfter().invoke-----");
System.out.println(" 此处意在执行核心业务逻辑之后,做一些日志记录操作等等");
System.out.println(" 可通过joinPoint来获取所需要的内容");
System.out.println("-----End of doAfter()------");
}
/**
* 核心业务逻辑调用正常退出后,不管是否有返回值,正常退出后,均执行此Advice
*
* @param joinPoint
*/
private void doReturn(JoinPoint joinPoint) {
System.out.println("-----doReturn().invoke-----");
System.out.println(" 此处可以对返回值做进一步处理");
System.out.println(" 可通过joinPoint来获取所需要的内容");
System.out.println("-----End of doReturn()------");
}
/**
* 核心业务逻辑调用异常退出后,执行此Advice,处理错误信息
*
* @param joinPoint
* @param ex
*/
private void doThrowing(JoinPoint joinPoint, Throwable ex) {
System.out.println("-----doThrowing().invoke-----");
System.out.println(" 错误信息:" + ex.getMessage());
System.out.println(" 此处意在执行核心业务逻辑出错时,捕获异常,并可做一些日志记录操作等等");
System.out.println(" 可通过joinPoint来获取所需要的内容");
System.out.println("-----End of doThrowing()------");
}
}
</span>
注:在方法中
for (int i = 0; i < joinPoint.getArgs().length; i++) {
System.out.println(joinPoint.getArgs()[i]);
}
可以读取咱们被切入方法的三叔和切入方法的名称等等。
大家可以看到,我们没有修改任何Controller中的代码。
总结:
Spring 中AOP的实现并不重要,最重要的是AOP的思想。