`
252190908
  • 浏览: 247300 次
文章分类
社区版块
存档分类
最新评论

Spring3.0 入门进阶(三):基于XML方式的AOP使用

 
阅读更多

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");
	}

}


分享到:
评论

相关推荐

    Spring2.5、3.0、3.1轻松入门+中级+高级教程14合一

    此外,Spring 2.5还引入了基于注解的Spring MVC,允许开发者在控制器类的方法上使用`@RequestMapping`等注解,从而避免XML配置。 2. **Spring 3.0** 进一步扩展了注解的使用,并引入了更多的新特性。例如,`@...

    Spring.3.x企业应用开发实战(完整版).part2

    4.11.2 使用基于Java类的配置信息启动Spring容器 4.12 不同配置方式比较 4.13 小结 第5章 Spring容器高级主题 5.1 Spring容器技术内幕 5.1.1 内部工作机制 5.1.2 BeanDefinition 5.1.3 InstantiationStrategy 5.1.4 ...

    Spring3.x企业应用开发实战(完整版) part1

    4.11.2 使用基于Java类的配置信息启动Spring容器 4.12 不同配置方式比较 4.13 小结 第5章 Spring容器高级主题 5.1 Spring容器技术内幕 5.1.1 内部工作机制 5.1.2 BeanDefinition 5.1.3 InstantiationStrategy 5.1.4 ...

    JAVA自学之路 七路线图明细

    10. **Spring**:学习Spring的IOC(Inversion of Control)和DI(Dependency Injection)原理,理解Spring架构,探索AOP和声明式事务处理。掌握Spring与Hibernate的整合,Spring对Web的支持,如Web Scope。其他...

    最新版Java视频学习路线图(内涵源码等获取方式)2.0(1).docx

    - **特点**:SpringBoot简化了基于Spring的应用程序开发,提供了一种快速构建独立、生产级的Spring应用的方式。 - **获取方式**:通过B站链接观看。链接为:https://www.bilibili.com/video/BV1PZ4y1j7QK - **...

    Java学习的详细路线图

    - **SSH集成**:了解Spring与Struts、Hibernate的集成方式。 - **JPA集成**:学习Spring与JPA的集成方法。 - **Hibernate(重点)**: - **检索映射技术**:理解ORM映射规则。 - **多表查询**:学会使用Hibernate...

    java学习路线

    #### 三、Web开发入门 - **第五阶段**:开始学习Web开发相关技术。 - 学习HTML/CSS/JavaScript等前端基础知识,这是进行Web开发的基础。 - 掌握基本的页面布局和样式设置方法,能够构建简单的静态网页。 - **第...

    Java各大文档包括sql,js这些

    3. **spring3.0_CN.chm** 和 **Spring2.5-中文参考手册.chm**:Spring是Java领域最流行的开源框架之一,用于构建企业级应用。这些文档详细解释了Spring框架的核心概念,如依赖注入、AOP(面向切面编程)、MVC、事务...

    Spring学习资料

    IoC 容器...............................................................................................................182.2 使用 Bean 定义................................................................

    java私塾全部笔记

    - 如何使用Spring实现AOP。 #### 十二、EJB3.0 - **EJB3.0简介** - EJB3.0相对于前代的主要改进。 - **SessionBean开发** - Session Bean的类型及其使用方法。 - **EntityBean开发** - Entity Bean的概念及其...

Global site tag (gtag.js) - Google Analytics