AOP是一个比较通用的概念,主要关注的内容用一句话来说就是"如何使用一个对象代理另外一个对象",不同的框架会有不同的实现,Aspectj 是在编译期就绑定了代理对象与被代理对象的关系,而Spring是在运行期间通过动态代理的方式来现实代理对象与被代理对象的绑定.具体的概念可以参考各自的文档:

Spring: http://docs.spring.io/spring/docs/3.2.1.RELEASE/spring-framework-reference/html/aop.html#aop-introduction

Aspecctj:http://eclipse.org/aspectj/

接下来仍然通过一个综合的例子来说明使用XML的方式如何使用Spring AOP

入口类

package com.eric.introduce;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.eric.introduce.aop.Contestant;
import com.eric.introduce.aop.IUser;
import com.eric.introduce.aop.Worker;
import com.eric.introduce.di.Performer; public class AOPCaller { private static final String CONFIG = "com/eric/introduce/aop/aop.xml";
private static ApplicationContext context = new ClassPathXmlApplicationContext(
CONFIG); public static void main(String[] args) {
// simpleAOPCase();
// arguementAOPTest();
demoDeclareParents();
} /**
* 演示了aop after-returning/before/after-throwing/around
* NOTE:如果在performer()方法执行的过程中产生异常且在around的方法中捕获了异常
* ,则after-throwing对应的方法不会被执行
*/
public static void simpleAOPCase() {
// 必须是接口类型,否则会包ClassCastException
Performer eric = (Performer) context.getBean("performer1");
eric.performer();
} /**
* 演示:aop 参数的传递方法
* 在用户开户成功后,发送一条问候短信,通过userName参数把用户名发给SMSGreeting
*/
public static void arguementAOPTest() {
IUser user = (IUser) context.getBean("user");
user.openAccount("Eric");
} /**
* 演示aop:declare-parents 的用法
* 在不改变源码的情况下,让Worker的子类包含Contestant接口的功能.
* getBean("worker")返回的对象即可以强转成Worker也可以强转成Contestant,而该对象只是实现了Worker接口
*/
public static void demoDeclareParents() {
Worker worker = (Worker) context.getBean("worker");
worker.hardWord();
((Contestant) worker).receiveAward(); Contestant worker2 = (Contestant) context.getBean("worker");
worker2.receiveAward();
((Worker) worker2).hardWord();
} }

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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <bean id="audience" class="com.eric.introduce.aop.Audience" />
<bean id="performer1" class="com.eric.introduce.di.InstrumentPerformer" /> <bean id="user" class="com.eric.introduce.aop.MobileUser" />
<bean id="smsgreeting" class="com.eric.introduce.aop.SMSGreeting" />
<!-- 为了使用aop:declare-parents特性,ITWorker必须声明为Worker接口的子类 -->
<bean id="worker" class="com.eric.introduce.aop.ITWorker" /> <aop:config>
<aop:aspect ref="audience">
<aop:pointcut
expression="execution(* com.eric.introduce.di.InstrumentPerformer.performer(..))"
id="performance" />
<aop:before method="takeSeat" pointcut-ref="performance" />
<aop:before method="turnOffCell" pointcut-ref="performance" />
<aop:after-returning method="applaud"
pointcut-ref="performance" />
<aop:after-throwing method="demandRefund"
pointcut-ref="performance" /> <aop:around method="calculateTime" pointcut-ref="performance" />
</aop:aspect> <aop:aspect ref="smsgreeting">
<aop:pointcut
expression="execution(* com.eric.introduce.aop.MobileUser.openAccount(String)) and args(userName)"
id="openaccount" />
<!-- 在用户开户成功后,发送一条问候短信,通过userName参数把用户名发给SMSGreeting -->
<aop:after-returning method="greeting"
pointcut-ref="openaccount" arg-names="userName" /> </aop:aspect> <aop:aspect>
<!-- 在不改变源码的情况下,让Worker的子类包含Contestant接口的功能 -->
<!-- com.eric.introduce.aop.Worker+ 说明针对Worker的子类有效 -->
<aop:declare-parents types-matching="com.eric.introduce.aop.Worker+"
implement-interface="com.eric.introduce.aop.Contestant"
default-impl="com.eric.introduce.aop.GraciousContestant" />
</aop:aspect> </aop:config> </beans>

其他相关类

after-returning/before/after-throwing/around 相关

package com.eric.introduce.aop;

import org.aspectj.lang.ProceedingJoinPoint;

/**
* 观众类
*
* @author Eric
*
*/
public class Audience {
public void takeSeat() {
System.out.println("AOP: Enter, take seat");
} public void turnOffCell() {
System.out.println("AOP: Show will start, turn off cell");
} public void applaud() {
System.out.println("AOP: Nice performance, applaud");
} public void demandRefund() {
System.out.println("AOP: Bad Performance, Return money");
} public void calculateTime(ProceedingJoinPoint joinPoint) {
long begintime = System.currentTimeMillis();
try {
joinPoint.proceed();
} catch (Throwable exception) {
System.out.println("Live Show has Exception");
} long end = System.currentTimeMillis();
System.out.println("AOP aRound: Spent Time:" + (end - begintime));
} } package com.eric.introduce.di; import java.util.List;
import java.util.Properties; /**
 * 定义一个表演者,这个表演者实现Performer接口
 *
 * @author Eric
 *
 */
public class InstrumentPerformer implements Performer {     /**
     * demo injection value
     */
    private String name;
    /**
     * demo injection Ref Bean
     */
    private Instrument instrument;     /**
     * demo injection original typ
     */
    private int age;     /**
     * demo injection internal bean
     */
    private Instrument privateInstrument;
    /**
     * demo injection List/Set/Array
     */
    private List<Fruit> favFruit;     /**
     * demo injection Properties/Map
     */
    private Properties properties;     @Override
    public void performer() {
        System.out.println("Normal Instrument:");
        try {
            Thread.sleep(1999);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        instrument.play();
        System.out.println("Special Instrument:");
        privateInstrument.play();
    }     @Override
    public void eatFruit() {
        for (Fruit fruit : favFruit) {
            fruit.eat();
        }
    }     @Override
    public void printProperties() {
        System.out.println(name + " Properties:\n");
        for (Object key : properties.keySet()) {
            System.out.println(key + " " + properties.getProperty((String) key)
                    + " \n");
        }
    }     public String getName() {
        return name;
    }     public void setName(String name) {
        this.name = name;
    }     public Instrument getInstrument() {
        return instrument;
    }     public void setInstrument(Instrument instrument) {
        this.instrument = instrument;
    }     public int getAge() {
        return age;
    }     public void setAge(int age) {
        this.age = age;
    }     public Instrument getPrivateInstrument() {
        return privateInstrument;
    }     public void setPrivateInstrument(Instrument privateInstrument) {
        this.privateInstrument = privateInstrument;
    }     public List<Fruit> getFavFruit() {
        return favFruit;
    }     public void setFavFruit(List<Fruit> favFruit) {
        this.favFruit = favFruit;
    }     public Properties getProperties() {
        return properties;
    }     public void setProperties(Properties properties) {
        this.properties = properties;
    } }  

aop:declare-parents 相关

package com.eric.introduce.aop;

/**
* 主要用来演示declare-parents
*
* @author Eric
*
*/
public interface Contestant {
public void receiveAward();
} package com.eric.introduce.aop; public class GraciousContestant implements Contestant { @Override
public void receiveAward() {
System.out.println("receiveAward was executed");
} } package com.eric.introduce.aop; public class ITWorker implements Worker {
public void hardWord() {
System.out.println("Worker is working hard!");
}
} package com.eric.introduce.aop; /**
* 主要用来演示declare-parents
*
* @author Eric
*
*/
public interface Worker {
public void hardWord();
}

参数相关

package com.eric.introduce.aop;

/**
* 定义一个问候接口
* @author Eric
*
*/
public interface IGreeting {
/**
* 定义了问候方法,但检测到有用户开户时,通过AOP机制自动发送问候短信
* @param name
*/
public void greeting(String name);
} package com.eric.introduce.aop; public interface IUser {
/**
* 开户操作
* @param name
*/
public void openAccount(String name);
} package com.eric.introduce.aop; public class MobileUser implements IUser { @Override
public void openAccount(String name) {
System.out.println("Register Succssful:" + name);
} } package com.eric.introduce.aop; /**
* 短信問候
* @author Eric
*
*/
public class SMSGreeting implements IGreeting { @Override
public void greeting(String name) {
System.out.println("Dear " + name + " Welcome to use CMCC");
} }

Spring3.0 入门进阶(三):基于XML方式的AOP使用的更多相关文章

  1. Spring3.0 入门进阶(1):从配置文件装载Bean

    Spring 已经盛行多年,目前已经处于3.0阶段,关于Spring的概念介绍性的东西网上已经很多,本系列博客主要是把一些知识点通过代码的方式总结起来,以便查阅. 作为入门,本篇主要介绍Bean的加载 ...

  2. SpringMVC入门(基于XML方式实现)

    ----------------------siwuxie095 SpringMVC 入门(基于 XML 方式实现) (一)搭建 SpringMVC 环境 1.先下载相关库文件,下载链接: (1)ht ...

  3. spring3.0使用annotation完全代替XML(三)

    很久之前写过两篇博客: spring3.0使用annotation完全代替XML spring3.0使用annotation完全代替XML(续) 用java config来代替XML,当时还遗留下一些 ...

  4. Spring-注入方式(基于xml方式)

    1.基于xml方式创建对象 <!--配置User类对象的创建 --> <bean id="user" class="com.at.spring5.Use ...

  5. Spring声明式事务管理(基于XML方式实现)

    --------------------siwuxie095                             Spring 声明式事务管理(基于 XML 方式实现)         以转账为例 ...

  6. 基于AspectJ的XML方式进行AOP开发

    -------------------siwuxie095                                 基于 AspectJ 的 XML 方式进行 AOP 开发         1 ...

  7. Spring系列之aAOP AOP是什么?+xml方式实现aop+注解方式实现aop

    Spring系列之aop aop是什么?+xml方式实现aop+注解方式实现aop 什么是AOP? AOP为Aspect Oriented Programming 的缩写,意识为面向切面的编程,是通过 ...

  8. MyBatis入门程序(基于XML配置)

    创建一个简单的MyBatis入门程序,实现对学生信息的增删改查功能(基于XML配置) 一.新建一个Java工程,导入MyBatis核心jar包.日志相关的jar包以及连接Oracle数据库所需驱动包, ...

  9. Cxf + Spring3.0 入门开发WebService

    转自原文地址:http://sunny.blog.51cto.com/182601/625540/ 由于公司业务需求, 需要使用WebService技术对外提供服务,以前没有做过类似的项目,在网上搜寻 ...

随机推荐

  1. [转] 搜索之双向BFS

    转自:http://www.cppblog.com/Yuan/archive/2011/02/23/140553.aspx 如果目标也已知的话,用双向BFS能很大程度上提高速度. 单向时,是 b^le ...

  2. VS2010安装中遇到的错误

    背景 用win7 64位系统安装VS2010遇到一个错误,网上查了各种资料也没有找到这种解决办法,后来自己找到了解决办法,分享一下,让他人少走一些弯路. 错误信息 安装过程中遇到如下错误: [08/2 ...

  3. 也谈http中get和post

    1.get和post区别: 从设计初衷考虑get是为了查询服务器资源(不改变服务器数据及状态,因此说它是安全和幂等的,但get请求参数一般是直接在url后面,浏览器地址栏中会被看到能保存书签及历史记录 ...

  4. K2 blackpearl 安装

    转:http://blog.csdn.net/gxiangzi/article/details/8432188 K2是国外的一款BPM引擎,基于MS的Workflow,关于它的详细介绍在我之前一片博客 ...

  5. 在英文 sql2005中 比较nvarchar 与 varchar的速度

    declare @str1 varchar(max); declare @count int; ; print 'begin' begin set @str1 = @str1 + '*'; ; end ...

  6. 38、FragmentStatePagerAdapter分页

    [ ViewPager ] ViewPager 如其名所述,是负责翻页的一个 View.准确说是一个 ViewGroup,包含多个 View 页,在手指横向滑动屏幕时,其负责对 View 进行切换.为 ...

  7. SQL遍历字符串的方法

    字符串穿越: 1.创建一个只存递增序列(1…n)的表——Temp,并将它与目标字符串所在的表Src进行笛卡尔运算.(Temp表的记录数要不小于遍历的目标字符串的长度) 2.过滤掉序列值大于串长的行. ...

  8. CodeForce---Educational Codeforces Round 3 Load Balancing 正题

    看到这题是我的想法就是肯定跟平均值有关但是接下来就不知道怎么做了 看完大神的正解数之后,原来发现是这么简单,但是就是不知道为啥一定是平均值和平均值加1,而不是平均值和平均值减1: 好啦下面就贴出大神的 ...

  9. redo buffer大小

    转载自http://blog.csdn.net/robinson1988/article/details/4729858 log buffer 是SGA中一块循环使用的内存区域,它一般很小,因为有4个 ...

  10. Ubuntu 12.04 中安装ubuntu-tweak出错

    错误信息: ubuntu-tweakE: Sub-process /usr/bin/dpkg returned an error code (1) 解决办法: 第一步:删除 /usr/share/py ...