前面几篇学习了Spring的依赖注入,这篇开始学习另一个核心功能——面向切面编程AOP。

  通过本文,你可以了解到:

  1 Spring xml规范

  2 通过配置文件实现面向切面编程

  3 对比与传统AOP编程

Spring的xml文件

  Spring的xml一般起名叫做bean.xml或者xxxapplication.xml这种,然后放在src下通过ClassPathXmlApplicationContext进行加载。文件的内容如下:

<?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="audience"class="com.spring.test.aop.Audience"/> <aop:config>
</aop:config>
</beans>

  最上面的是xml的编码,这个就不解释了。

  下面的<beans>是Spring的配置标签,beans里面几个重要的属性

  xmlns:

  是默认的xml文档解析格式,即spring的beans。地址是http://www.springframework.org/schema/beans。

  通过设置这个属性,所有在beans里面声明的属性,可以直接通过<>来使用,比如<bean>等等。

  xmlns:xsi:

  是xml需要遵守的规范,通过URL可以看到,是w3的统一规范,后面通过xsi:schemaLocation来定位所有的解析文件。

  xmlns:aop:

  这个是重点,是我们这里需要使用到的一些语义规范,与面向切面AOP相关。

  xmlns:tx:

  Spring中与事务相关的配置内容。

  

  一个XML文件,只能声明一个默认的语义解析的规范。

  例如上面的xml中就只有beans一个是默认的,其他的都需要通过特定的标签来使用,比如aop,它自己有很多的属性,如果要使用,前面就必须加上aop:xxx才可以。比如上面的aop:config。

  类似的,如果默认的xmlns配置的是aop相关的语义解析规范,那么在xml中就可以直接写config这种标签了。

基于配置的AOP编程过程

  首先,如果要在工程中使用AOP需要几个jar包:

  1 Aop的核心包,即org.springframework.aop-xxx.jar

  2 Spring的联盟包:aopalliance-1.0.jar

  3 aspectJ相关的jar包:aspectjrt.jar aspectjweaver.jar

  4 如果使用了动态代理,还需要添加cglib相关的jar包:cglib.zip

  首先需要一个AOP的切面类,用于定义各种响应事件

package com.spring.test.aop;

public class Audience {
public void takeSeats(){
System.out.println("The audience is taking their seats.");
}
public void turnOffCellPhones(){
System.out.println("The audience is turning off their cellphones");
}
public void applaud(){
System.out.println("CLAP CLAP CLAP");
}
public void demandRefund(){
System.out.println("Boo! We want money back");
}
}

  然后在bean.xml中编写aop:config的相关内容:

...省略beans的定义内容

    <bean id="audience" class="com.spring.test.aop.Audience"/>

    <bean id="sax" class="com.spring.test.setter.Saxophone"/>
<bean id="kenny" class="com.spring.test.setter.Instrumentalist">
<property name="song" value="Jingle Bells" />
<property name="age" value="25" />
<property name="instrument" ref="sax"/>
</bean> <aop:config proxy-target-class="true">
<aop:aspect ref="audience">
<aop:pointcut id="performance" expression="execution(* com.spring.test.action1.Performer.perform(..))"/> <aop:before pointcut-ref="performance" method="takeSeats"/>
<aop:before pointcut-ref="performance" method="turnOffCellPhones"/>
<aop:after-returning pointcut-ref="performance" method="applaud"/>
<aop:after-throwing pointcut-ref="performance" method="demandRefund"/>
</aop:aspect>
</aop:config>
</beans>

  这里面的aop:pointcut 就是使用AspectJ来定位的。意思是:当执行com.spring.test.action1.Performer的perform方法时,就会触发该切面的事件响应。

  而Performer以及Instrumentalist等等的代码,就在下面简单的都罗列出来了:

  配置文件:bean.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"
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="audience" class="com.spring.test.aop.Audience"/> <bean id="sax" class="com.spring.test.setter.Saxophone"/>
<bean id="kenny" class="com.spring.test.setter.Instrumentalist">
<property name="song" value="Jingle Bells" />
<property name="age" value="25" />
<property name="instrument" ref="sax"/>
</bean> <aop:config proxy-target-class="true">
<aop:aspect ref="audience">
<aop:pointcut id="performance" expression="execution(* com.spring.test.action1.Performer.perform(..))"/> <aop:before pointcut-ref="performance" method="takeSeats"/>
<aop:before pointcut-ref="performance" method="turnOffCellPhones"/>
<aop:after-returning pointcut-ref="performance" method="applaud"/>
<aop:after-throwing pointcut-ref="performance" method="demandRefund"/>
</aop:aspect>
</aop:config>
</beans>

  表演者接口:Performer.java

package com.spring.test.action1;

public interface Performer {
void perform() throws PerformanceException;
}

  表演者实现类:Instrumentalist.java

package com.spring.test.setter;

import com.spring.test.action1.PerformanceException;
import com.spring.test.action1.Performer; public class Instrumentalist implements Performer{
private String song;
private int age;
private Instrument instrument;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSong() {
return song;
}
public void setSong(String song) {
this.song = song;
}
public Instrument getInstrument() {
return instrument;
}
public void setInstrument(Instrument instrument) {
this.instrument = instrument;
}
public Instrumentalist(){}
public Instrumentalist(String song,int age,Instrument instrument){
this.song = song;
this.age = age;
this.instrument = instrument;
}
public void perform() throws PerformanceException {
System.out.println("Instrumentalist age:"+age);
System.out.print("Playing "+song+":");
instrument.play();
}
}

  内部bean接口:Instrument.java

package com.spring.test.setter;

public interface Instrument {
public void play();
}

  内部bean实现类:Saxophone.java

package com.spring.test.setter;

public class Saxophone implements Instrument {
public Saxophone(){}
public void play() {
System.out.println("TOOT TOOT TOOT");
}
}

  测试主函数:main

package com.spring.test.setter;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.spring.test.action1.PerformanceException; public class test {
public static void main(String[] args) throws PerformanceException {
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); Instrumentalist performer = (Instrumentalist)ctx.getBean("kenny");
performer.perform(); }
}

  运行结果:

The audience is taking their seats.
The audience is turning off their cellphones
Instrumentalist age:25
Playing Jingle Bells:TOOT TOOT TOOT
CLAP CLAP CLAP

  通过这种声明方式,可以 快速的实现切点与切面的整合,成为下面这种格式的新代码:

class{
try{
audience.takeSeats();
audience.turnOffCellphones(); performance.perform(); audience.applaud();
}catch(Exception){
audience.demandRefund();
}
}

  面向切面的好处,要在实际工作中多加领会才可以,常用的场景就是日志的记录了。

与传统的AOP编程相比

  前面也做过一个传统的spring aop的实现方法:http://www.cnblogs.com/xing901022/p/4143696.html

  不得不说,通过ProxyFactoryBean达到的面向切面的编程,过于复杂,光是那几个功能就要好好理解一番。

  而基于配置的AOP使用就要简单的多,只需要一个切面的程序,然后通过配置文件就可以完全解耦的融入到切点中。

基于配置的Spring AOP的更多相关文章

  1. 基于注解的Spring AOP的配置和使用

    摘要: 基于注解的Spring AOP的配置和使用 AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不 ...

  2. Spring Aop(七)——基于XML配置的Spring Aop

    转发:https://www.iteye.com/blog/elim-2396043 7 基于XML配置的Spring AOP 基于XML配置的Spring AOP需要引入AOP配置的Schema,然 ...

  3. 基于注解的Spring AOP示例

    基于注解的Spring AOP示例 目录 在XML配置文件中开启 @AspectJ 支持 声明切面及切入点 声明通知 测试 结语 在XML配置文件中开启 @AspectJ 支持 要使用Spring的A ...

  4. 基于注解的Spring AOP的配置和使用--转载

    AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  5. 基于Aspectj表达式配置的Spring AOP

    AOP(Aspect-Oriented Programming, 面向切面编程):是一种新的方法论, 是对传统OOP(Object-Oriented Programming, 面向对象编程)的补充. ...

  6. 基于配置的Spring MVC3

    网上查找的spring mvc3大部分都是基于注射的方式,总感觉注射有点怪怪.不利于后期扩展和项目管理,于是特意写下这篇基于xml配置的Spring MVC3.以供大家參考. 怎么建立web项目和下载 ...

  7. 基于 Annotation 的 Spring AOP 权限验证方法的实现

    1. 配置 applicationContext 在 Spring 中支持 AOP 的配置非常的简单,只需要在 Spring 配置文件 applicationContext.xml 中添加: < ...

  8. 基于注解的Spring AOP拦截含有泛型的DAO

    出错场景 1.抽象类BaseDao public abstract class BaseDao<T> { public BaseDao() { entityClass = (Class&l ...

  9. 基于XML配置的spring aop增强配置和使用

    在我的另一篇文章中(http://www.cnblogs.com/anivia/p/5687346.html),通过一个例子介绍了基于注解配置spring增强的方式,那么这篇文章,只是简单的说明,如何 ...

随机推荐

  1. ECharts 雷达图怎么在类目值下面显示数值

    需要实现的效果: 官网里面的demo显示数值,都是在拐点处: [解决] 1.只显示类目 <div id="mychart" style="width:300px;h ...

  2. 剑指offer——面试题9:用两个栈实现队列

    #include "Queue.h" // ====================测试代码==================== void Test(char actual, ...

  3. 从零开始学Linux(11)--more

    more命令,是将文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空格键(space)就往下一页显示,按 b 键就会往回(back)一页显示,而且还 ...

  4. oracle 基础知识(五)--回滚(commit和rollback)

    一,commit 01,commit干了啥 commit 就是提交的意思.也就是当你把99%的东西都做好了,然后你执行最后一步的操作...再commit前的话你可能啪啪啪啪啪,敲了几百条sql DML ...

  5. 安卓获取输入法高度与ViewTreeObserver讲解

    目录 安卓获取输入法高度 前言 清单 开始 ViewTreeObserver讲解 获取输入法高度原理 思路 实现 关于ViewTreeObserver 定义 继承 摘要 获取View高度的三种方法 源 ...

  6. codeigniter读取数据库的公共配置并全局缓存的实现方案

    引言 学习CodeIgniter大概有几天了.从第一天了解后,对CI情有独钟,比较符合我的风格.其实一直以来对框架这块不太敏感.自己长时间的开发,也有一套自己的开发风格和习惯.但是这年头,你说你不会框 ...

  7. [Verilog] parameter

    parameter和localparam的作用范围均为本模块,区别在于前者可用于在实例化模块的时候进行参数的传递. 用已定义的参数对变量赋值时,按照补码的方式处理,若出现溢出的情况,则截取低位.

  8. C# 服务端控件 asp:RadioButton 选择选中值

    1.服务端控件RadioButton <asp:RadioButton ID="rbNewUser" runat="server" GroupName=& ...

  9. 深入理解JavaScript系列(17):面向对象编程之概论

    介绍 在本篇文章,我们考虑在ECMAScript中的面向对象编程的各个方面(虽然以前在许多文章中已经讨论过这个话题).我们将更多地从理论方面看这些问题. 特别是,我们会考虑对象的创建算法,对象(包括基 ...

  10. 基于RBAC模式的权限管理系统设计概要

    很多人都知道以角色为基础的权限管理设计(RBAC),但是大部分人似懂非懂,不知道完整的权限管理系统都包括哪些内容.  在此以权限管理的使用场景来说明一下完整的权限管理内容.     一是鉴权管理,即权 ...