引言:
继前一节(面向方法编程AOP学习之二 —— “原始时代”
)的学习引发了一些思考,如前面总结所说的,商人老板无法接受为了一个表演家,就要造一个剧院,这样的成本实在太高太高了,这里需要做的是一个剧院可以允许不同的表演者表演不同的节目,这才是真正的一种进化
,才是一种进步
。
主题:
JDK的动态代理
描述:
在JDK1.3开始,就出现了动态代理的实现,jdk提供了java.lang.reflect.InvocationHandler这么样的一个接口来动态的实现,在执行某方法时,去处理一些事情。
场景制造:
如前一节的场景,这个老板又找到了一个新的表演家,这个表演家不仅仅只会一个表演能力,他会吉他,会钢琴。这时,老板把他带到了一个大的剧院里面,这里面的设备齐全,道具都有都,任由表演家天马行空。
角色:
# 多才的表演家:Player2
# 老板:Boss
# 设备齐全的剧院:DynaProxyTheatre
作用:
/**
* 表演家接口
*/
public interface IPlayer2 {
public void playPiano();
public void playGuitar();
}
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框架所体现的进步性。
下一节:待续....
此刻窗外看去,杭州正沉溺在细雨濛濛之中...
分享到:
相关推荐
NULL 博文链接:https://sammor.iteye.com/blog/1054464
AOP 面向服务 面向方面编程 AOP 面向服务 面向方面编程 AOP 面向服务 面向方面编程 AOP 面向服务 面向方面编程
Spring AOP面向方面编程原理Spring AOP面向方面编程原理Spring AOP面向方面编程原理Spring AOP面向方面编程原理Spring AOP面向方面编程原理Spring AOP面向方面编程原理Spring AOP面向方面编程原理
Spring,面向切面编程AOP例子!AOP(Aspect Oriented Programming)!
AOP是OOP的延续,是(Aspect Oriented Programming)的缩写,意思是面向切面编程。 OO注重的是我们解决问题的方法(封装成Method),而AOP注重的是许多解决问题的方法中的共同点,是对OO思想的一种补充! 主要的功能是:...
关于Spring框架的aop简介
Spring AOP面向方面编程原理:AOP概念,主要介绍面向对象的概念及原理,及作者的一些理解。
aop,面向切面编程
NULL 博文链接:https://lihaiming.iteye.com/blog/2273380
Spring-aop面向切面编程实例 日志系统,权限控制等.
本教程介绍 AOP 及其基本概念。AOP 及其相关的工具使您可以将基本横切关注点(如日志记录和安全)的代码,与程序的核心应用逻辑相分离。AOP 通过使代码更具有可读性、更不容易出错以及更容易设计和维护,改善了代码...
AOP 面向方面编程 技术总结 AOP 面向方面编程 技术总结
面向横截面编程面向横截面编程面向横截面编程面向横截面编程面向横截面编程
AOP面向切面编程.ppt
一直对AOP面向切面编程的理解很模糊的同学可以看看。
AOP面向切面编程实例,可当作业提交。.net代码亲测,完全正确运行。
Spring 实现AOP需要三个第三方的jar包,分别是aspectjrt.jar,aspectjweaver.jar,aopalliance-1.0.jar
aop 面向切面编程 demo,通过一个小案例来讲解,aop在andriod开发中运用
2.1 面向切面编程AOP入门 软件系统中的一些功能需要用到应用程序的多个地方,但是我们又不想在每个点都明确调用它们。日志、安全和事务管理的确都很重要,但它们是否为应该被应用对象主动调用呢?如果让应用对象只...
Spring4AOP 面向切面编程实例之方法拦截实例 一下利用Spring4的最后一个版本Spring4.3.9,实现简单的方法拦截实例。 Eclipse 建立java工程,导入必要的jar包,工程目录如下: