引言:
继前一节(面向方法编程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框架所体现的进步性。
下一节:待续....
此刻窗外看去,杭州正沉溺在细雨濛濛之中...
分享到:
相关推荐
在本文中,我们将深入探讨MOP的一个重要概念——“原始时代”,这个术语通常用来形容早期的、较为基础的面向方法编程实践。在这一阶段,程序员们开始意识到将程序分解为一系列独立的功能模块或方法的重要性,但尚未...
### 面向方面编程(AOP)详解 #### AOP概述 面向方面编程(Aspect Oriented Programming,简称AOP)是一种程序设计范式,它作为面向对象编程(Object-Oriented Programming,简称OOP)的补充和发展。AOP的核心理念...
面向方面编程(AOP,Aspect-Oriented Programming)是一种编程范式,旨在解决传统面向对象编程(OOP)中横切关注点的问题。横切关注点是指那些跨越多个对象或模块,但又不直接属于单一模块职责的功能,如日志记录、...
Spring AOP 是一种面向切面的编程实现,它是Spring框架的核心功能之一,用来解决传统面向对象编程(OOP)中难以管理的横切关注点问题。在Spring中,AOP主要通过代理机制实现,允许开发者将关注点分离,将通用的辅助...
在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,用于处理系统中的横切关注点,如日志、事务管理等。本篇主要探讨如何在AOP的Advice方法中获取目标方法的参数。 首先,理解AOP的基本概念至关重要。在...
面向切面编程(AOP,Aspect Oriented Programming)是Spring框架中的一个重要特性,它提供了一种模块化和声明式的方式来处理程序中的横切关注点,如日志、事务管理、安全控制等。AOP的核心概念包括切面、通知、连接...
### Spring AOP面向方面编程原理:AOP概念详解 #### 一、引言 随着软件系统的日益复杂,传统的面向对象编程(OOP)逐渐暴露出难以应对某些横切关注点(cross-cutting concerns)的问题。为了解决这一挑战,面向方面编程...
面向切面编程(Aspect-Oriented Programming,AOP)是Spring框架的核心特性之一,它提供了一种优雅的方式来处理系统的横切关注点,如日志、事务管理、性能监控和权限控制等。在Spring中,AOP主要通过代理模式实现,...
面向切面编程(AOP,Aspect Oriented Programming)是一种编程范式,旨在将系统中的关注点分离,使得代码更加模块化,易于维护和扩展。在传统的面向对象编程(OOP)中,业务逻辑往往与日志、事务管理、权限控制等横...
### Spring AOP面向方面编程原理详解 #### 一、引言与定义 Spring AOP(Aspect Oriented Programming)是Spring框架中的一个核心组件,用于实现面向切面编程。AOP是一种编程范式,旨在将横切关注点(Cross-cutting...
### AOP面向切面编程详解 #### 一、AOP概览 AOP(Aspect-Oriented Programming,面向切面编程)是一种编程思想和技术,它作为OOP(面向对象编程)的一种补充,主要解决了OOP在处理横切关注点方面的不足。在传统的...
在Spring框架中,面向切面编程(AOP)是一个关键特性,它允许我们进行横切关注点的分离,如日志、事务管理等,从而提高代码的可维护性和可复用性。本文将深入探讨Spring AOP中的`AfterThrowing`通知类型,这是处理...
面向方面编程(AOP)是一种编程范式,旨在提高软件开发的模块化程度,特别是通过将关注点分离,以便更好地管理复杂系统。AOP的核心概念是“方面”(Aspect),它封装了跨越多个类的横切关注点,如事务管理、日志记录、...
在Java世界中,Spring框架以其强大的功能和灵活性深受开发者喜爱,尤其在面向切面编程(AOP)方面,Spring提供了非常全面的支持。AOP是一种编程范式,它允许程序员定义“切面”,这些切面可以封装关注点,如日志、...
在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点分离,将横切关注点(如日志、事务管理、安全检查等)与核心业务逻辑解耦。"9Spring AOP 盗梦空间之四——Around"这个标题暗示我们...
本教程介绍 AOP 及其基本概念。AOP 及其相关的工具使您可以将基本横切关注点(如日志记录和安全)的代码,与程序的核心应用逻辑相分离。AOP 通过使代码更具有可读性、更不容易出错以及更容易设计和维护,改善了代码...
#### 三、面向方面编程的实现方法 AOP可以通过多种方式实现,包括但不限于: 1. **静态编织**:在编译阶段将切面代码编织到目标对象中。 2. **动态编织**:在运行时动态地将切面代码插入到目标对象中。 3. **语言...
面向横截面编程面向横截面编程面向横截面编程面向横截面编程面向横截面编程
在IT行业中,Spring框架是Java企业级应用开发的首选,其强大的功能之一就是AOP(面向切面编程)。本文将详细解析Spring AOP的三种实现方式,帮助你深入理解这一重要概念。 首先,理解AOP的基本概念至关重要。AOP是...
面向切面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,它旨在提高软件的模块化程度,通过将关注点分离到不同的“切面”中来实现。在.NET环境中,AOP通常通过拦截器(Interceptor)或动态代理...