使用面想对象(Object-Oriented Programming,OOP)包含一些弊端,当需要为多个不具有继承关系的对象引入公共行为时,例如日志,安全检测等。我们只有在每个对象中引入公共行为,这样程序中就产生了大量的代码,程序就不便于维护了,所以就有了一个面向对象编程的补充---面向切面编程(Aspect-Oriented Programming, AOP),AOP关注的方向是横向的,OOP关注的时纵向的;OOP中模块的基本单元是class,而AOP中基本的模块单元称作Aspect。

AOP的其主要作用是,在不修改源代码的情况下给某个或者一组操作添加额外的功能。像日志记录,事务处理,权限控制等功能,都可以用AOP来“优雅”地实现,使这些额外功能和真正的业务逻辑分离开来,软件的结构将更加清晰。AOP是OOP的一个强有力的补充。

Key Terms

学习AOP,我们需要关注一些技术名词:

  1. Aspect: 切面,横向贯穿于多个类的某个服务,比如事务处理
  2. Join Point:又叫point cut,是指那些方法需要被执行"AOP"
  3. Advice:join point上特定的时刻执行的操作,Advice有几种不同类型,下文将会讨论(通俗地来讲就是起作用的内容和时间点)。
  4. Introduction: 给对象增加方法或者属性
  5. Target object: Advice起作用的对象
  6. AOP proxy:为实现AOP所实现的代理,在Spring中实现代理的方式有两种,JDK代理和CGLIB代理
  7. Weaving:将Advice织入join point的过程

Advice的类型:

  1. Before advice: 在执行join point之前执行
  2. After returning advice: 执行在join point这个方法返回之后的advice
  3. After throwing advice: 当方法抛出异常之后执行
  4. After (finally) advice: Advice在方法退出之后执行。
  5. Around advice: 包围一个连接点的通知,如方法调用。这是最 强大的通知。Aroud通知在方法调用前后完成自定义的行为。它们负责选择继续执行连接点或通过 返回它们自己的返回值或抛出异常来短路执行。

Spring AOP的使用

有三种方式使用Spring AOP,分别是:@Aspect-based(Annotation),Schema-based(XML),以及底层的Spring AOP API。其中@Aspect-based是使用最多的一种方式。我们所讲的例子也是基于@Aspect-based(Annotation)这种方式的

Aspect based

配置

Spring AOP Maven依赖

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.1.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.1.RELEASE</version>
</dependency> <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency> <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>

xml文件配置

 <?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!-- 使能AOP-->
<aop:aspectj-autoproxy/> <!-- 声明一个切面-->
<bean id="myAspect" class="com.mj.spring.aop.MyAspect"></bean>
<!--声明AOP target-->
<bean id="userManager" class="com.mj.spring.aop.UserManager"></bean>
</beans>

编码

定义切面类

<!--定义切面类-->
@Aspect
public class MyAspect { //定义切点, 这个切点的使用范围是: 定义在com.mj.spring.aop包下的所有方法
@Pointcut("execution(* com.mj.spring.aop.*.*(..))")
public void aPointcut() {
} //定义Before Advice
@Before("aPointcut()")
public void beforeAdvice() {
System.out.println("before advice is executed!");
} //定义AfterReturning Advice
@AfterReturning(pointcut = "aPointcut()", returning = "r")
public void afterReturningAdvice(String r) {
if (r != null)
System.out.println("after returning advice is executed! returning String is : " + r);
} //定义After Advice
@After("aPointcut()")
public void AfterAdvice() {
System.out.println("after advice is executed!");
} @After("aPointcut() && args(str)")
public void AfterAdviceWithArg(String str) {
System.out.println("after advice with arg is executed!arg is : " + str);
} //定义afterThrowingAdvice Advice
@AfterThrowing(pointcut = "aPointcut()", throwing = "e")
public void afterThrowingAdvice(Exception e) {
System.out.println("after throwing advice is executed!exception msg is : " + e.getMessage());
} //定义around advice
@Around(value="execution(public String com.mj.spring.aop.UserManager.getUser(..))")
public void aroundSayHello(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("Around Before !! ");
joinPoint.proceed();
System.out.println("Around After !! ");
} }

定义AOP target类

public class UserManager {
/*这个方法需要一个参数*/
public void addUser(String user) {
System.out.println("addUser(String str) method is executed!");
} public void deleteUser() {
System.out.println("deleteUser() method is executed!");
} /*这个方法返回一个字符串*/
public String getUser() {
System.out.println("getUser() method is executed!");
return "Hello";
} /*这个方法抛出一个异常*/
public void editUser() throws Exception {
throw new Exception("something is wrong.");
}
}

测试类

public class UserManagerTest {

private ApplicationContext applicationContext=null;
@Before
public void setUp() throws Exception {
applicationContext=new ClassPathXmlApplicationContext("ApplicationContext.xml");
} @Test
public void shoud_get_user_maneger_bean() throws Exception {
UserManager userManager = (UserManager) applicationContext.getBean("userManager");
assertThat(userManager!=null,is(true));
}
@Test
public void should_apply_before_advice_and_after_advice_and_after_advice_with_arg() throws Exception{
UserManager userManager = (UserManager) applicationContext.getBean("userManager");
userManager.addUser("Jun.Ma");
}
@Test
public void should_apply_before_advice_and_after_advice() throws Exception{
UserManager userManager = (UserManager) applicationContext.getBean("userManager");
userManager.deleteUser();
} @Test
public void should_apply_before_advice_and_after_advice_and_after_throwing_advice() throws Exception{
UserManager userManager = (UserManager) applicationContext.getBean("userManager");
userManager.editUser();
} @Test
public void should_apply_before_advice_and_after_advice_after_return_advice() throws Exception{
UserManager userManager = (UserManager) applicationContext.getBean("userManager");
userManager.getUser();
}
@Test
public void should_apply_around_advice_and_before_advice_and_after_advice_after_return_advice() throws Exception{
UserManager userManager = (UserManager) applicationContext.getBean("userManager");
userManager.getUser();
}
}

Reference

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#aop-enable-aspectj-java Spring Document Reference

http://blog.psjay.com/posts/summary-of-spring-3-aop/ Spring AOP 3 Summary

源码git路径: git@github.com:jma19/spring.git

Spring AOP简述的更多相关文章

  1. Spring5.0源码学习系列之Spring AOP简述

    前言介绍 附录:Spring源码学习专栏 在前面章节的学习中,我们对Spring框架的IOC实现源码有了一定的了解,接着本文继续学习Springframework一个核心的技术点AOP技术. 在学习S ...

  2. Spring AOP及事务配置三种模式详解

    Spring AOP简述 Spring AOP的设计思想,就是通过动态代理,在运行期对需要使用的业务逻辑方法进行增强. 使用场景如:日志打印.权限.事务控制等. 默认情况下,Spring会根据被代理的 ...

  3. (转)实例简述Spring AOP之间对AspectJ语法的支持(转)

    Spring的AOP可以通过对@AspectJ注解的支持和在XML中配置来实现,本文通过实例简述如何在Spring中使用AspectJ.一:使用AspectJ注解:1,启用对AspectJ的支持:通过 ...

  4. Spring(五)AOP简述

    一.AOP简述 AOP全称是:aspect-oriented programming,它是面向切面编号的思想核心, AOP和OOP既面向对象的编程语言,不相冲突,它们是两个相辅相成的设计模式型 AOP ...

  5. java框架篇---spring AOP 实现原理

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  6. Spring(一)简述

    一.Spring简述 一段费话 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2 ...

  7. Spring AOP 详解

    AOP使用场景 AOP用来封装横切关注点,具体可以在下面的场景中使用: Authentication 权限 Caching 缓存 Context passing 内容传递 Error handling ...

  8. Spring AOP简介

    AOP简述 AOP的概念早在上个世纪九十年代初就已经出现了,当时的研究人员通过对面向对象思想局限性的分析研究出了一种新的编程思想来帮助开发者减少代码重复提高开发效率,那就是AOP,Aspect-Ori ...

  9. Spring AOP 实现原理

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

随机推荐

  1. My安卓知识1--SQLite数据库

    前一阵子做了一个小项目,关于android的,想记录一下学到的一些知识,做成一个小系列吧,算是对自己这一个多月来的见证.首先说明,这些知识也都是从网上各处学习来的,我自己做了一些小整理. 1.SQLi ...

  2. 【转】Crontab定时任务配置

    原文出处:http://www.cnblogs.com/kerrycode/p/3238346.html CRONTAB概念/介绍 crontab命令用于设置周期性被执行的指令.该命令从标准输入设备读 ...

  3. 02-Swift初体验

    Playground是什么? 从Xcode6开始出现(Swift开始出现) 翻译为:操场/游乐场 对于学习Swift基本语法非常方便 所见即所得(快速查看结果) 语法特性发生改变时,可以快速查看. S ...

  4. 关于Linux的 /sbin权限问题

    安装ubuntu一段时间后新增了用户,突然发现原来的用户用不了 ifconfig ,提示找不到命令 一试之下发现/sbin/ifconfig,可以,明白了是因为用户新增了,系统不认为当前用户是唯一用户 ...

  5. XMLHttpRequest cannot load file:///E:/userdialog.html?_=1465888805734. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-reso

    做前端写静态页面时,采用的是jq easyui框架 在ie与webkit总是加载的时候总是在loading... 而firefox却是正常加载的,总以为是代码写错了, 经过再三的检查以及百度查找,确认 ...

  6. 构建angular项目

    1. 安装yo与gulp bower $ npm install -g yo $ npm install -g gulp bower 2. 快速创建     $ npm install -g gene ...

  7. node学习笔记(三)

    //事件驱动events //events是node最重要的模块没有之一,因为node.js本身的架构就是事件式的,而他提供了唯一的接口,所以堪称node.js事件编程的基石; //events几乎被 ...

  8. Windows 下 ffmpeg 转 mp4

    最近在研究所有视频格式转  mp4 因为html5 只支持mov MP4 等格式..查阅了 很多资料发现  转成flv  很简单.. 可是要转 mp4 就难了... 经过我不屑的努力..终于转换成功了 ...

  9. yii安装 /You don't have permission to access on this server

    在安装yii的时候 ,当打开了init.bat进行配置的时候小黑本弹出了个小黑框立刻就关闭了,  进入cmd模式再打开init.bat就出现了"You don't have permissi ...

  10. C#中语音合成简单使用

    我使用的是vs2013 1.在项目中添加引用,项目->添加引用->COM选择Microsoft Speech Object Library 2.在需要使用语音合成的地方调用代码: SpVo ...