初见Spring之AOP编程
来源:互联网 发布:microsoft办公软件 编辑:程序博客网 时间:2024/05/17 08:59
初见Spring之AOP编程
Spring其中一个主要特性就是支持AOP编程,AOP编程可以将多个类或者方法中的重复逻辑抽取出来,提高了代码重用性和可维护性质,AOP编程是对面向对象编程的延伸和补充。本文不介绍AOP编程的概念,主要描述Spring对AOP编程的支持。
Spring对AOP编程提供了两种支持,第一种是Spring AOP也就是Spring自己实现的AOP编程,第二中是AspectJ,Spring的核心库集成了AspectJ,AspectJ也是Spring建议使用的AOP框架,本文主要介绍Spring对AspectJ的支持。
一丶Spring AOP编程基本概念
AOP编程主要涉及如下几个基本的概念:
(1)pointcut(切入点),通俗的来说就是待增强的方法,严格指向待增强方法的位置。
(2)adavice(通知),通知就是增强的方法,对目标对象增强代码的实现都是写在通知中,AspectJ中提供了五种通知:
1.before(前置通知):该通知在切入点之前执行。
2.after-returning(后置通知):该通知在切入点方法执行完之后执行,如果切入点方法抛出了异常,该通知不会执行。
3.around(环绕通知):该通知在切入点方法执行前后执行
4.after-throwing(异常通知):在切入点方法抛出异常之后执行该通知
5.after(最终通知):在切入点方法执行完毕后指向,假如切入点方法抛出了异常该方法照样执行
(3) Aspect(切面):从编程的角度来看,切面就是所有增强方法的集合,在切面里面定义和实现了各种增强方法。
二丶基于XML的AspectJ AOP编程
Spring提供两种方法对AspectJ的支持,第一个便是利用xml配置的方法来完成AspectJ AOP编程,下面举例在说明这个方法。
定义一个Teacher类和一个切面类,Teacher类代表待增强的对象,切面类里面实现由所有的通知,下面来探讨下Spring基于XML的方法如何实现AOP编程。
Teacher类:
public class TeacherDaoImpl implements TeacherDao{ @Override publicvoid login() { // TODO Auto-generated method stub System.out.println("teacher登录完成"); }}
切面类:
publicclass TeacherAspect{ /** * @param point 保存有切入点信息 */ publicvoidbeforeNotification(JoinPoint point){ System.out.println("权限验证"); } /** * @param point 保存切入点信息 * @param returnValue 切点点方法的返回值 */ publicvoid afterNotification(JoinPointpoint,Object returnValue){ System.out.print("登录成功跳转到首页"); } /** * @param point 环绕通知对应的特殊切入点,可以调用增强对象的方法 * @throws Throwable 执行切点方法时抛出的异常信息 */ publicObject AroundrNotification(ProceedingJoinPoint point) throws Throwable{ System.out.println("权限验证"); Object object = point.proceed(); System.out.println("登录成功,跳转到首页"); returnobject; } /** * @param point * @param e 目标方法抛出异常 */ publicvoidafterThrowingNotification(JoinPoint point,Throwable e){ System.out.println("登录失败"); } /** * @param point 切入点信息 */ publicvoid finalNotification(JoinPointpoint){ System.out.println("清除登录痕迹");; } }
测试代码:
public class MainAspectJ { publicstatic void main(String [] args){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); TeacherDao teacherDao = (TeacherDao)context.getBean("teacherDao"); teacherDao.login(); }}
Spring配置文件:
<!--配置增强对象--> <bean name="teacherDao" class="AspectJ.TeacherDaoImpl"/> <!--配置切面 --> <bean name="teacherAspect"class="AspectJ.TeacherAspect"/> <!--AspecJ AOP配置核心--> <aop:config> <aop:aspect ref="teacherAspect"> <aop:pointcut id="teacherPoint"expression="execution(* AspectJ.*.*(..))"/> <aop:before method="beforeNotification"pointcut-ref="teacherPoint"/> <aop:after-returning method="beforeNotification"pointcut-ref="teacherPoint" returning="returnValue"/> <aop:after-throwing method="afterThrowingNotification" throwing="e"pointcut-ref="teacherPoint"/> <aop:after method="finalNotification"pointcut-ref="teacherPoint"/> </aop:aspect> </aop:config>
图1 前置通知以及后置通知
结合Spring的配置文件和图1的结果可以看到,Spring完成对目标对象的增强,可以看见after通知执行了,after-throwing通知并没有执行,after-throwing通知只有下发生异常的时候执行,after通知无论是否发生异常都执行。
对Teacher类做如下修改来验证上述结论(其他代码内容不变)
public class TeacherDaoImpl implements TeacherDao{ @Override publicvoid login() { // TODO Auto-generated method stub int i=1/0; System.out.println("teacher登录完成"); }}
图2 发生异常时候执行情况
从图2的运行结果可以看出来,发生异常的时候,after-throwing通知会执行,但是after-returning通知不会执行,final通知会执行
三丶基于注解的AOP编程
通过上述的流程可以发现基于xml的AOP编程需要编写繁杂的xml文件,所以提供基于注解编写AOP的方法。下面通过一个和上述相似的例子来介绍基于注解的
ManDaoImpl类:被增强对象
@Repository("man")public class ManDaoImpl implements ManDao{ @Override publicvoid login() { // TODO Auto-generated method stub }}
ManDaoAspectJ:切面对象
@Aspect@Componentpublic class ManDaoAspect { //定义一个切入点@Pointcut("execution(* AspectJ.*.*(..))") privatevoid mepointCut(){} @Before(value="mepointCut()") publicvoid befoeNotification(JoinPointpoint){ System.out.println("登录校验"); } @AfterReturning(value="mepointCut()",returning="result") publicvoid afterNotification(JoinPointpoint,Object result){ System.out.print("登录成功"); } @Around(value="mepointCut()") publicObject roundNotification(ProceedingJoinPoint point) throws Throwable{ System.out.println("权限校验"); Object object = point.proceed(); System.out.println("登录成功"); returnobject; } @AfterThrowing(value="mepointCut()",throwing="e") publicvoid AfterThrowing(JoinPoint point,Throwablee){ System.out.println("登录失败"); } @After(value="mepointCut()") publicvoid finalNotification(JoinPointpoint){ System.out.println("清除登录痕迹"); }}
测试代码对象:
publicclass MainAspectJ { publicstatic void main(String [] args){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //TeacherDao teacherDao =(TeacherDao)context.getBean("teacherDao"); //teacherDao.login(); ManDao manDao= (ManDao)context.getBean("man"); manDao.login(); }}
Spring配置文件写法:
<!-- 指定需要扫描的包,使注解生效 --> <context:component-scan base-package="AspectJ"/> <!--AOP注解生效--> <aop:aspectj-autoproxy/>
测试结果:
图3基于注解的AOP测试结果
从上述这个基于注解配置AOP的例子中,我们可以观察到基于注解配置AOP和基于xml配置AOP在通知配置,切面配置,切入点配置方面是完全是一一对应的,但是基于注解的AOP编程显然比基于XML的AOP编程更为简洁。这里特别需要注意基于注解额AOP编程在配置文件中,必须介绍扫描注解以及配置AOP注解生效。
- 初见Spring之AOP编程
- 初见Spring之JDBC
- 初见Spring之事务管理
- Spring进阶之AOP编程
- Spring AOP: Spring之面向方面编程
- Spring AOP: Spring之面向方面编程
- Spring AOP: Spring之面向方面编程
- Spring AOP: Spring之面向方面编程
- 面试之网络编程初见
- Spring之面向方面编程(AOP)
- Spring之面向方面编程(AOP)
- Spring 基础教程之五:AOP编程介绍
- Spring之AOP实现面向切面编程
- Spring之AOP,面向切面编程
- Spring之AOP面向切面编程
- Spring自学之XML式AOP编程
- Spring实践之面向切面编程(AOP)
- Spring boot之AOP面向切面编程
- 在Word中添加图或表自动编号与引用功能
- HTML中的 href 和 src 的区别
- js特效 人形时钟
- poj 3009
- Frafment 的show和hide
- 初见Spring之AOP编程
- Java基础——冒号标记代码块的作用
- 图像复原与重建
- 将 Spark Streaming + Kafka direct 的 offset 保存进入Zookeeper(二)
- Vijos 雷曼兔(csapc)
- 【算法】一种用于云计算的SPSO算法
- android killer连接夜神模拟器
- 文章标题
- C/C++学习笔记