Spring AOP整理

示例展示

AOP(Aspect Oriented Programming),是面向切面编程的技术。AOP基于IoC基础,是对OOP的有益补充。
AOP之所以能得到广泛认可,主要是因为它将应用系统拆分分了2个部分:核心业务逻辑及横向的通用逻辑,也就是所谓的切面。例如,所有大中型应用都要涉及到的持久化管理、事务管理、权限管理、日志管理和调试管理等。使用AOP技术,可以让开发人员只专注核心业务,而通用逻辑则使用AOP技术进行横向切入,由专人去处理这些通用逻辑,会使得任务简单明了,提高开发和调试的效率。

下面我们来举个例子(具体代码参见右侧源码,只适合菜鸟看)

示例场景

场景:歌手演唱音乐,演唱之前观众要坐在座位上并且关闭手机,演唱结束后,观众们满意就鼓掌,不满意就抛出不高兴的异常。
分析这个场景,某歌手演唱音乐是核心业务逻辑,而演唱之前和之后观众们的动作都是通用的,属于横向的通用逻辑。

示例原理图

实现步骤

1.首先建立一个歌手接口 Performer。
2.再建立爵士音乐歌手类 DukePerformer 来实现这个接口,类中包括了歌手的个人信息。
3.然后定义观众类 Audience,包含观众的行为通知。
4.完成之后,我们便可以在配置文件 applicationContext.xml 中进行aop切面配置。关键代码如下:

<aop:config>
	<!-- 定义切入点 -->
	<aop:pointcut id="sing" expression="execution(* *.perform(..))"/>
	<!-- 定义切面 -->
	<aop:aspect ref="audience">
		<!-- 前置通知 -->
		<aop:before method="takeSeat" pointcut-ref="sing" />
		<aop:before method="turnOffPhone" pointcut-ref="sing" />
		<!-- 返回后通知 -->
		<aop:after-returning method="applaud" pointcut-ref="sing" />
		<!-- 抛出后通知 -->
		<aop:after-throwing method="unHappy" pointcut-ref="sing" />
	</aop:aspect>
</aop:config>

5.编写测试类代码,获得Spring中定义的Bean对象,执行perform表演方法,查看后台是如何运行的。
正常情况下,控制台会打印如下的信息:

观众坐在座位上。
观众关闭手机。
duke 开始演唱歌曲。
观众鼓掌,掌声经久不息...

知识准备

什么是AOP?
AOP: (Aspect Oriented Programming) 面向切面编程。是目前软件开发中的一个热点,也是Spring框架中容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。

什么是OOP?AOP与其有什么区别?
AOP、OOP在字面上虽然非常类似,但却是面向不同领域的两种设计思想。OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。 而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差异。
通俗来讲,OOP面向名词领域,AOP面向动词领域。

如何理解AOP?
举个简单例子,比如你想在每次写字之前都检查一下笔里有没有墨水了,通常的做法是:在写字这个Action里调用判断是否有墨水的方法。这样做的不好一个方面是,写字的Action和是否有墨水的方法产生了依赖,如果你有十几支不同的笔写字,每一个笔的Action里都要调用判断是否有墨水的方法;另一个方面是:就面向对象的程序设计来说,写字和判断是否有墨水的方法是同一等级的,如果你让写字这个动作来判断是否有墨水不够人性化,有违面向对象的程序设计的思想。
如果用Spring的AOP,是把写字的Action作为一个切面,在每次调用不同的笔来写字的方法之前,调用判断是否有墨水的方法。它是由<aop:config/>标签在Spring配置文件里定义的。

资源准备

1:jar包下载地址:spring jar包
2.详细学习参考spring参考手册spring参考手册

示例

AOP的实现可以使用注解和xml配置文件两种方式,这里使用xml配置文件方式。示例的过程见左侧的“示例展示”,下面是源码:
首先建立一个接口Performer类

1 package demoinfo.spring.aop;
2 
3 public interface Performer {
4     //表演歌曲
5     public void perform();
6 }
View Code

再建立一个接口实现类DukePerformer

 1 package demoinfo.spring.aop;
 2 
 3 public class DukePerformer implements  Performer{
 4     private String name;  
 5     public void setName(String name)  {  
 6         this.name=name;  
 7     }  
 8     public String getName()  {  
 9         return this.name;  
10     }  
11     public void perform() {  
12         System.out.println(this.name+" 开始演唱歌曲。");  
13     }  
14 } 
View Code
Audience观众业务类
 1 package demoinfo.spring.aop;
 2 
 3 public class Audience {  
 4     public void takeSeat()  {  
 5         System.out.println("观众坐在座位上。");  
 6     }  
 7     public void turnOffPhone()   {  
 8         System.out.println("观众关闭手机。");  
 9     }  
10     public void applaud()  {  
11         System.out.println("观众鼓掌,掌声经久不息...");  
12     }  
13     public void unHappy()  {  
14         System.out.println("观众不高兴.");  
15     }  
16 }  
View Code

配置文件applicationContext.xml代码如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 4     xsi:schemaLocation="http://www.springframework.org/schema/beans
 5            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 6            http://www.springframework.org/schema/aop
 7            http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
 8     <!-- AOP学习时的配置 -->
 9     <bean id="DukePerformer" class="demoinfo.spring.aop.DukePerformer">
10         <property name="name" value="duke" />
11     </bean>
12     <bean id="audience" class="demoinfo.spring.aop.Audience" />
13 
14     <aop:config>
15         <!-- 定义切入点 -->
16         <aop:pointcut id="sing" expression="execution(* *.perform(..))"/>
17         <!-- 定义切面 -->
18         <aop:aspect ref="audience">
19             <!-- 前置通知 -->
20             <aop:before method="takeSeat" pointcut-ref="sing" />
21             <aop:before method="turnOffPhone" pointcut-ref="sing" />
22             <!-- 返回后通知 -->
23             <aop:after-returning method="applaud" pointcut-ref="sing" />
24             <!-- 抛出后通知 -->
25             <aop:after-throwing method="unHappy" pointcut-ref="sing" />
26         </aop:aspect>
27     </aop:config>
28     <!-- AOP学习时的配置 -->
29 </beans>
View Code

最后测试类代码如下:

 1 package demoinfo.spring.aop;
 2 
 3 import org.springframework.context.ApplicationContext;  
 4 import org.springframework.context.support.FileSystemXmlApplicationContext;  
 5 
 6 public class SpringDemo {  
 7     public static void main(String[] args) {  
 8         //获得Spring中定义的Bean实例(对象)
 9         ApplicationContext ctx=new FileSystemXmlApplicationContext(
10                 "classpath:demoinfo/spring/aop/applicationContext.xml");  
11         Performer per=(Performer)ctx.getBean("DukePerformer");  
12         per.perform();  
13     }  
14 }  
View Code
原文地址:https://www.cnblogs.com/acm-bingzi/p/5809606.html