`
sammor
  • 浏览: 413273 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

面向方法编程AOP学习之三 —— “进化论”

阅读更多

引言:

       继前一节(面向方法编程AOP学习之二 —— “原始时代” )的学习引发了一些思考,如前面总结所说的,商人老板无法接受为了一个表演家,就要造一个剧院,这样的成本实在太高太高了,这里需要做的是一个剧院可以允许不同的表演者表演不同的节目,这才是真正的一种进化 ,才是一种进步

 

主题:

       JDK的动态代理

 

描述:

       在JDK1.3开始,就出现了动态代理的实现,jdk提供了java.lang.reflect.InvocationHandler这么样的一个接口来动态的实现,在执行某方法时,去处理一些事情。

 

场景制造:

       如前一节的场景,这个老板又找到了一个新的表演家,这个表演家不仅仅只会一个表演能力,他会吉他,会钢琴。这时,老板把他带到了一个大的剧院里面,这里面的设备齐全,道具都有都,任由表演家天马行空。

 

角色:

# 多才的表演家:Player2
# 老板:Boss  
# 设备齐全的剧院:DynaProxyTheatre

 

作用:

  • 多才的表演家:Player2
/**
 * 表演家接口
 */
public interface IPlayer2 {

	public void playPiano();

	public void playGuitar();
}
  •  老板(Boss)
package chat3;

/**
 * 很会赚钱的老板
 */
public class Boss {

	/**
	 * 卖票
	 */
	public void shellTicket() {
		System.out.println("shell many tickets ");
	}

	/**
	 * 给酬劳
	 */
	public void givePlayerMoney() {
		System.out.println("give a little money to player.");
	}

	/**
	 * 逃跑
	 */
	public void runAway() {
		System.out.println("The play is broken , the boss run away in a hurry");
	}
}
  •  设备齐全的剧院(DynaProxyTheatre)
package chat3;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 可变式接收各种表演者<br>
 * 对剧院对各种表演者都可以支持
 */
public class DynaProxyTheatre implements InvocationHandler {

	/**
	 * 目标的表演者
	 */
	public Object targetPlayer;

	/**
	 * 用来接收目标表演者
	 * 
	 * @param target
	 *            表演者
	 * @return 返回代理的接口
	 */
	public Object bind(Object target) {
		this.targetPlayer = target;
		return Proxy.newProxyInstance(targetPlayer.getClass().getClassLoader(),
				targetPlayer.getClass().getInterfaces(), this);
	}

	/**
	 * 演出开始
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result = null;
		Boss boss = new Boss();

		boss.shellTicket();
		System.out.println(" begin =>" + method.getName());
		try {
			// 动态调用方法
			result = method.invoke(targetPlayer, args);
		} catch (Exception e) {
			boss.runAway();
		}
		System.out.println(" end =>" + method.getName());
		boss.givePlayerMoney();

		return result;
	}
}
 

 来一场演出吧

 

@Test
	public void testChat3() {
		IPlayer2 player2 = (IPlayer2) new DynaProxyTheatre()
				.bind(new Player2());
		player2.playGuitar();
		player2.playPiano();
	}

 

 

演出过程

 

shell many tickets 
 begin =>playGuitar
playing guitar... 
 end =>playGuitar
give a little money to player.

shell many tickets 
 begin =>playPiano
playing piano... 
 end =>playPiano
give a little money to player.

 

总结1:

     JDK的动态代理,把从重复的编写代理类带到了一个动态的代理类中。可以为不同的方法接口都进行处理。就这样,剧院和表演家的关系进行了一次解耦了。

    但这里面还是有一个的问题,代理者(剧院)与切入处理者(Boss)并没有解耦掉。

 

 

 

 

 

 

作用变换:

 

老板的变换(Boss2)

package chat3;

import java.lang.reflect.Method;

/**
 * 很会赚钱的老板
 */
public class Boss2 implements IBoss {

	public void shellTicket(Method method) {
		System.out.println("shell many tickets ");
	}

	public void givePlayerMoney(Method method) {
		System.out.println("give a little money to player.");
	}

	public void runAway(Method method) {
		System.out.println("The play is broken , the boss run away in a hurry");
	}
}

 

剧场的变换(DynaProxyTheatre2):

 

package chat3;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 可变式接收各种表演者<br>
 * 对剧院对各种表演者都可以支持
 */
public class DynaProxyTheatre2 implements InvocationHandler {

	/**
	 * 目标的表演者
	 */
	public Object targetPlayer;

	/**
	 * 用来接收Boss的到来
	 */
	public Object proxy;

	/**
	 * 用来接收目标表演者
	 * 
	 * @param target表演者
	 * @param proxy 切入的处理者(Boss)
	 * @return 返回代理的接口
	 */
	public Object bind(Object target, Object proxy) {
		this.targetPlayer = target;
		this.proxy = proxy;
		return Proxy.newProxyInstance(targetPlayer.getClass().getClassLoader(),
				targetPlayer.getClass().getInterfaces(), this);
	}

	/**
	 * 演出开始
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result = null;

		// 代理与切入处理者的解耦调用方法
		Class shellTicket = this.proxy.getClass();
		// 反射得到操作者的shellTicket方法
		Method start = shellTicket.getDeclaredMethod("shellTicket",
				new Class[] { Method.class });
		// 反射执行shellTicket方法
		start.invoke(this.proxy, new Object[] { method });

		System.out.println(" begin =>" + method.getName());
		try {
			// 动态调用方法
			result = method.invoke(targetPlayer, args);
		} catch (Exception e) {
			Method runAway = shellTicket.getDeclaredMethod("runAway",
					new Class[] {});
			runAway.invoke(this.proxy, new Object[] { method });
		}
		System.out.println(" end =>" + method.getName());
		Method givePlayerMoney = shellTicket.getDeclaredMethod(
				"givePlayerMoney", new Class[] { Method.class });
		givePlayerMoney.invoke(this.proxy, new Object[] { method });

		return result;
	}
}

 

再一次的演出:

 

   同上

 

演示结果:

 

shell many tickets 
 begin =>playGuitar
playing guitar... 
 end =>playGuitar
give a little money to player.

shell many tickets 
 begin =>playPiano
playing piano... 
 end =>playPiano
give a little money to player.

 

总结2:

      从第二步,进入了新的改造,在这里,把剧院(代理类)和老板(切入处理类),进行了解耦。当然,在这基础上的更进一步的实现,封装还可以使我们在使用AOP的过程更加的简单,便捷。这也就是后面Spring与AspectJ这些AOP框架所体现的进步性。

 

下一节:待续....

 

此刻窗外看去,杭州正沉溺在细雨濛濛之中...

 

分享到:
评论
5 楼 zhangbenben 2011-06-02  
icezx 写道
楼主请用jdk动态代理个没有接口的普通类试试

可以的,用cglib可以实现的。
4 楼 sammor 2011-05-31  
icezx 写道

实际开发中接口不是必须的哦,也就jdk是必须的而已。


没能理解你这句话的意思哦,能再解释清楚点吗?
3 楼 icezx 2011-05-30  
sammor 写道
icezx 写道
楼主请用jdk动态代理个没有接口的普通类试试

这样子是不可以的,
[url]
   public Object bind(Object target) { 
        this.targetPlayer = target; 
         return Proxy.newProxyInstance(targetPlayer.getClass().getClassLoader(), 
                targetPlayer.getClass().getInterfaces(), this); 
   } 
[/url]

这里是传进这个普通类的接口进去做代理的,接口是必需的。



实际开发中接口不是必须的哦,也就jdk是必须的而已。
2 楼 sammor 2011-05-27  
icezx 写道
楼主请用jdk动态代理个没有接口的普通类试试

这样子是不可以的,
[url]
   public Object bind(Object target) { 
        this.targetPlayer = target; 
         return Proxy.newProxyInstance(targetPlayer.getClass().getClassLoader(), 
                targetPlayer.getClass().getInterfaces(), this); 
   } 
[/url]

这里是传进这个普通类的接口进去做代理的,接口是必需的。
1 楼 icezx 2011-05-27  
楼主请用jdk动态代理个没有接口的普通类试试

相关推荐

    面向方法编程AOP学习之二 —— “原始时代”

    在本文中,我们将深入探讨MOP的一个重要概念——“原始时代”,这个术语通常用来形容早期的、较为基础的面向方法编程实践。在这一阶段,程序员们开始意识到将程序分解为一系列独立的功能模块或方法的重要性,但尚未...

    面向方面编程AOP

    ### 面向方面编程(AOP)详解 #### AOP概述 面向方面编程(Aspect Oriented Programming,简称AOP)是一种程序设计范式,它作为面向对象编程(Object-Oriented Programming,简称OOP)的补充和发展。AOP的核心理念...

    AOP——面向服务--面向方面编程

    面向方面编程(AOP,Aspect-Oriented Programming)是一种编程范式,旨在解决传统面向对象编程(OOP)中横切关注点的问题。横切关注点是指那些跨越多个对象或模块,但又不直接属于单一模块职责的功能,如日志记录、...

    面向切面编程aop简介

    Spring AOP 是一种面向切面的编程实现,它是Spring框架的核心功能之一,用来解决传统面向对象编程(OOP)中难以管理的横切关注点问题。在Spring中,AOP主要通过代理机制实现,允许开发者将关注点分离,将通用的辅助...

    Spring中的AOP(五)——在Advice方法中获取目标方法的参数

    在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,用于处理系统中的横切关注点,如日志、事务管理等。本篇主要探讨如何在AOP的Advice方法中获取目标方法的参数。 首先,理解AOP的基本概念至关重要。在...

    Spring面向切面编程AOP

    面向切面编程(AOP,Aspect Oriented Programming)是Spring框架中的一个重要特性,它提供了一种模块化和声明式的方式来处理程序中的横切关注点,如日志、事务管理、安全控制等。AOP的核心概念包括切面、通知、连接...

    Spring AOP面向方面编程原理:AOP概念

    ### Spring AOP面向方面编程原理:AOP概念详解 #### 一、引言 随着软件系统的日益复杂,传统的面向对象编程(OOP)逐渐暴露出难以应对某些横切关注点(cross-cutting concerns)的问题。为了解决这一挑战,面向方面编程...

    Spring-aop面向切面编程实例

    面向切面编程(Aspect-Oriented Programming,AOP)是Spring框架的核心特性之一,它提供了一种优雅的方式来处理系统的横切关注点,如日志、事务管理、性能监控和权限控制等。在Spring中,AOP主要通过代理模式实现,...

    面向切面 aop

    面向切面编程(AOP,Aspect Oriented Programming)是一种编程范式,旨在将系统中的关注点分离,使得代码更加模块化,易于维护和扩展。在传统的面向对象编程(OOP)中,业务逻辑往往与日志、事务管理、权限控制等横...

    Spring AOP面向方面编程原理Spring AOP面向方面编程原理

    ### Spring AOP面向方面编程原理详解 #### 一、引言与定义 Spring AOP(Aspect Oriented Programming)是Spring框架中的一个核心组件,用于实现面向切面编程。AOP是一种编程范式,旨在将横切关注点(Cross-cutting...

    AOP面向切面编程总结

    ### AOP面向切面编程详解 #### 一、AOP概览 AOP(Aspect-Oriented Programming,面向切面编程)是一种编程思想和技术,它作为OOP(面向对象编程)的一种补充,主要解决了OOP在处理横切关注点方面的不足。在传统的...

    8Spring AOP盗梦空间之三 ——AfterThrowing

    在Spring框架中,面向切面编程(AOP)是一个关键特性,它允许我们进行横切关注点的分离,如日志、事务管理等,从而提高代码的可维护性和可复用性。本文将深入探讨Spring AOP中的`AfterThrowing`通知类型,这是处理...

    AOP 面向方面编程 技术总结

    面向方面编程(AOP)是一种编程范式,旨在提高软件开发的模块化程度,特别是通过将关注点分离,以便更好地管理复杂系统。AOP的核心概念是“方面”(Aspect),它封装了跨越多个类的横切关注点,如事务管理、日志记录、...

    Spring使用AOP的三个jar包

    在Java世界中,Spring框架以其强大的功能和灵活性深受开发者喜爱,尤其在面向切面编程(AOP)方面,Spring提供了非常全面的支持。AOP是一种编程范式,它允许程序员定义“切面”,这些切面可以封装关注点,如日志、...

    9Spring AOP 盗梦空间之四——Around

    在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点分离,将横切关注点(如日志、事务管理、安全检查等)与核心业务逻辑解耦。"9Spring AOP 盗梦空间之四——Around"这个标题暗示我们...

    面向方面编程的Aop介绍

    本教程介绍 AOP 及其基本概念。AOP 及其相关的工具使您可以将基本横切关注点(如日志记录和安全)的代码,与程序的核心应用逻辑相分离。AOP 通过使代码更具有可读性、更不容易出错以及更容易设计和维护,改善了代码...

    面向方面编程_AOP_介绍.pdf

    #### 三、面向方面编程的实现方法 AOP可以通过多种方式实现,包括但不限于: 1. **静态编织**:在编译阶段将切面代码编织到目标对象中。 2. **动态编织**:在运行时动态地将切面代码插入到目标对象中。 3. **语言...

    AOP面向横截面编程

    面向横截面编程面向横截面编程面向横截面编程面向横截面编程面向横截面编程

    Spring AOP面向切面三种实现

    在IT行业中,Spring框架是Java企业级应用开发的首选,其强大的功能之一就是AOP(面向切面编程)。本文将详细解析Spring AOP的三种实现方式,帮助你深入理解这一重要概念。 首先,理解AOP的基本概念至关重要。AOP是...

    AOP面向切面编程实例

    面向切面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,它旨在提高软件的模块化程度,通过将关注点分离到不同的“切面”中来实现。在.NET环境中,AOP通常通过拦截器(Interceptor)或动态代理...

Global site tag (gtag.js) - Google Analytics