AOP in Spring

是不是已经对包裹在每个业务周围的异常处理、事务管理、性能监控、日志记录等重复出现的代码感到厌倦,那么是时候轮到AOP出场了。不得不承认程序员的惰性有时候会是一件好事(毕竟提高生产率的终极目标是增加休息时间)。有一个统计类的项目,业务过程相当复杂,从输入参数到输出结果,中间会产生大量的临时数据。客户的要求是程序需要记录下每一个中间过程的临时数据,这样方便验证统计过程是否正确。客户以前是程序员,非常迷信封闭式开发并固执地要求了解开发中的每个细节。AOP在他写代码的年代还没有,所以项目组专门为他写了一个演示程序。

  定义一个Aspect类,其中包括切入点表达式和四个通知(@Before、@After、@AfterReturning、@AfterThrowing),并且该类由@Component注入到Spring容器中。

package com.mmh.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; @Component
@Aspect
public class Aspector { private static final String pointCut = "execution(* com.mmh.business.*.*(..))"; @Before(pointCut)
public void before(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature().getName() + ": 开始执行");
} @After(pointCut)
public void after(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature().getName() + ": 结束执行");
} @AfterReturning(pointcut = pointCut, returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println(joinPoint.getSignature().getName() + " 执行结果: "
+ result);
} @AfterThrowing(pointcut = pointCut, throwing = "error")
public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {
System.out.println(joinPoint.getSignature().getName() + " 抛出异常: "
+ error);
}
}

  定义一个模拟业务计算的Calculate类以及两个子业务类,Add和Divide。在实际的商业化项目中最好做这样的分解,努力保持一个类、函数和模块只完成一个任务(Single Responsibility Principle的宗旨)。这样在需求发生变化或算法出现问题时,修改代码的成本会相对较低。

package com.mmh.business;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component("Calculate")
public class Calculate { @Autowired
private Add addMethod; @Autowired
private Divide divideMethod; public int calculate(int a, int b) {
return divideMethod.divide(addMethod.add(a, b), b);
}
}
package com.mmh.business;

import org.springframework.stereotype.Component;

@Component("Add")
public class Add { public int add(int a, int b) {
return a + b;
}
}
package com.mmh.business;

import org.springframework.stereotype.Component;

@Component("Divide")
public class Divide { public int divide(int a, int b) {
return a / b;
}
}

  写一个简单的测试类让程序运行起来。在程序的输出中可以清楚地看到各个子业务执行情况,这就满足了客户的需求。

package com.mmh.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mmh.business.Calculate; public class Test { public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"appContext.xml"); Calculate p = (Calculate) context.getBean("Calculate");
p.calculate(1, 2);
}
}
// 运行结果:
/**
* calculate: 开始执行
* add: 开始执行
* add: 结束执行
* add 执行结果: 3
* divide: 开始执行
* divide: 结束执行
* divide 执行结果: 1
* calculate: 结束执行
* calculate 执行结果: 1
*/

  最后还是要把Spring配置好,让它为我们提供优秀的服务。因为在这个演示程序中使用的是注解的方式向Spring容器中注入Bean,也用注解的方式配置AOP,所以配置文件相当简单。这种简单的方式是否在任何应用场景中都适用呢?当然不是,这种方式缺乏灵活性,需求变化时,开发人员必须要修改代码以及编译代码。

<?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:context="http://www.springframework.org/schema/context"
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/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"> <context:component-scan base-package="com.mmh" /> <aop:aspectj-autoproxy /> </beans>

AOP in Spring的更多相关文章

  1. 死磕Spring之AOP篇 - Spring AOP常见面试题

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  2. 死磕Spring之AOP篇 - Spring AOP自动代理(一)入口

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  3. 死磕Spring之AOP篇 - Spring 事务详解

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  4. 【spring 5】AOP:spring中对于AOP的的实现

    在前两篇博客中,介绍了AOP实现的基础:静态代理和动态代理,这篇博客介绍spring中AOP的实现. 一.采用Annotation方式 首先引入jar包:aspectjrt.jar && ...

  5. AOP及spring AOP的使用

    介绍 AOP是一种概念(思想),并没有设定具体语言的实现. AOP是对oop的一种补充,不是取而代之. 具体思想:定义一个切面,在切面的纵向定义处理方法,处理完成之后,回到横向业务流. 特征 散布于应 ...

  6. SpringBoot CGLIB AOP解决Spring事务,对象调用自己方法事务失效.

    对于像我这种喜欢滥用AOP的程序员,遇到坑也是习惯了,不仅仅是事务,其实只要脱离了Spring容器管理的所有对象,对于SpringAOP的注解都会失效,因为他们不是Spring容器的代理类,Sprin ...

  7. 浅谈spring中AOP以及spring中AOP的注解方式

    AOP(Aspect Oriented Programming):AOP的专业术语是"面向切面编程" 什么是面向切面编程,我的理解就是:在不修改源代码的情况下增强功能.好了,下面在 ...

  8. AOP:spring 的Annotation配置

    1.文件目录: 2.实体类 package com.wangcf.po; public class User { private int id; private String name; privat ...

  9. 【AOP】Spring AOP基础 + 实践 完整记录

    Spring AOP的基础概念 ============================================================= AOP(Aspect-Oriented Pr ...

随机推荐

  1. Html5 の 微信飞机大战

    (function () { var imageUrl = "images/"; //获取画布对象 var c = $("#game-box").get(0); ...

  2. 关于小改CF协同过滤至MapReducer上的一些心得

    至上次重写ID3 MR版之后,手贱继续尝试CF.之前耳闻CF这两年内非常火,论内某大神也给了单机版(90%代码来自于其).所以想试试能否改到MR上.整体来说,CF本身的机制以相似性为核心,与迭代调用几 ...

  3. C语言库函数大全及应用实例二

    原文:C语言库函数大全及应用实例二                                              [编程资料]C语言库函数大全及应用实例二 函数名: bioskey 功 能 ...

  4. WPF应用程序支持多国语言解决方案

    原文:WPF应用程序支持多国语言解决方案 促使程序赢得更多客户的最好.最经济的方法是使之支持多国语言,而不是将潜在的客户群限制为全球近70亿人口中的一小部分.本文介绍四种实现WPF应用程序支持多国语言 ...

  5. Django查询的琐碎记录

    我的需求是这样的,获取指定用户的获“赞”总数. 用户 models.py class UserProfile(models.Model): user = models.OneToOneField(Us ...

  6. CSS学习笔记:Media Queries

    CSS3提供了Media Queries(媒体查询)的概念,可以利用它查询以下数据: 1.浏览器窗口的宽和高: 2.设备的宽和高: 3.设备的手持方向,横向/竖向: 4.分辨率. @media规则的语 ...

  7. Android总结的基本机制监控事件

    研究上午Android底层机制事件监视器,例如下面的摘要: 内核驱动监控硬件状态和行为,由uevent机制将事件发送到用户空间: 通过用户空间UeventObserver从内核监控uevent,处理. ...

  8. 批处理中set截取字符具体解释

    set截取字符具体解释  在批处理中,set的功能有点繁杂:设置变量.显示环境变量的名及值.做算术运算.等待用户的输入.字符串截取.替换字符串,是我们经常使用的命令之中的一个. 在字符串截取方面,新手 ...

  9. 分享12款经典时尚的HTML5应用

    分享伟大,呵呵.今天给大家分享一下收集的12个HTML5小特效. 我整理一下源码,给大家打包一下,我博客园上传文件大小有限,传不了了. 需要的请留下邮箱就行了,觉得好的话,不要忘了点赞哦~ 1.CSS ...

  10. Web服务器性能/压力测试工具http_load、webbench、ab、Siege使用教程

    一.http_load 程序非常小,解压后也不到100K http_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工 具,它可以以一个单一的进程运行,一般 ...