自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework(1)

 

自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework

——MyFramework

 

原创: 牛超 TOKYO

Email/MSNncfire_msn@hotmail.com

QQ10867910

http://fanblogs.jp/dbaeo7zl/

 

 

 

关键字(Keywords):面向对象(OOP)、框架(Framework)、反射(Reflection)、设计模式(Design Pattern)、扩展标识语言(XML)、依赖注入(Dependency Injection)、控制反转容器(IoC)、横切点(Pointcut)、面向方面编程(AOP

 

 

 

前言

关于IoCAOP的理论,现在到处都能找到相关的资料,一句话,勿在浮砂筑高台。。。尽管高台上看海滩极有情趣。本次设计的目标是模仿Spring的机能以及其对象XML定义格式来自行打造轻量级的Framework,不是拿来主义而算得上是Spring的模仿秀。本框架设计的初衷只是为了避免目前闲暇的工作所毒害,防止被睡意飘浮的空气所传染。由几行读取XML的代码勾起了本人对以往研究Spring超迷人设计理论的神经与模仿设计的欲望。曾希望走在架构前沿,但自从领了日元就再没有研究过模式耦合之如的概念,整天被无章堆砌的代码恶心着。倒是这段时间没有了挠人的需求变更与计划进度,便冲动这么一时,算是兴趣驱动之使然。

话规正席,MyFramework。。。暂且这么叫吧。利用XMLJAVA反射机制完成依赖注入、对象动态构造、通用对象深度克隆机能以实现IoCAOP两大核心功能。既然有两大核心功能,代码篇幅和注释应该。。。,但因本人使用的是日语环境,日文键盘也用得不顺,Framework与测试代码只有使用蹩脚的E文注释来填充,望各位海涵并多加指正。

 

 

MyFramework之前瞻

IoC是整个框架设计的基础。第一次看到这个名词犯晕其实几篇文章看下来觉得挺简单。写这篇文章也是为了抛砖引玉。毕竟不足充斥着行进之路。首先,设计XML文档并形成自己的标签格式,以便脑中形成相对客观的目的性,即让Framework能够无二义性地读取其中定义的对象,针对定义片断解说如下。

一、对于单一的对象定义,Object标签namean Employee对象,Singleton定义为单件(不是对象本身的属性,EmployeeBean没有是否为单身这么个属性;具体指系统中仅存一份无副本,见设计模式):

<object name = "anemployee" class = "app.beans.EmployeeBean" singleton = "false">

<EmpId>5</EmpId>

<EmpCode>0005</EmpCode>

<EmpName>ttt</EmpName>

<Birthday>2007-11-04</Birthday>

<Resume>no resume</Resume>

</object>

二、聚合对象Object结点元素子标签以elemen t表示,其属性defpackage表示如果当前对象或是聚合元素的类定义没有指定Package,则将其指定为defpackage所定义的内容,属性iscollection表明该对象为聚合对象。

<object name = "employeelist" class = "java.util.ArrayList" defpackage = "app.beans" iscollection = "true">

<element class = "EmployeeBean">

<EmpId>1</EmpId>

<EmpCode>0001</EmpCode>

<EmpName>aaa</EmpName>

<Birthday>2007-12-04</Birthday>

<Resume>0</Resume>

</element>

 

<element class = "EmployeeBean">

<EmpId>2</EmpId>

<EmpCode>0002</EmpCode>

<EmpName>bbb</EmpName>

<Birthday>2007-12-04</Birthday>

<Resume>0</Resume>

</element>

 

<element class = "app.beans.EmployeeBean">

<EmpId>3</EmpId>

<EmpCode>0003</EmpCode>

<EmpName>ccc</EmpName>

<Birthday>2007-12-04</Birthday>

<Resume>0</Resume>

</element>

<element class = "app.beans.EmployeeBean">

<EmpId>4</EmpId>

<EmpCode>0004</EmpCode>

<EmpName>ccc</EmpName>

<Birthday>2007-12-04</Birthday>

<Resume>0</Resume>

</element>

</object>

三、依赖注入,参照对象employeedao做为empbo构造子参数注入,构造子标签定义为<constructor>其内部定义组成构造参数列表。

<object name="empbo" class="app.bo.HrBOImpl" singleton="true">

<constructor>

  <arg object="employeedao" />

</constructor>

</object>

四、AOP 装备(因可随意加/卸载以增强类的功能,装备这个名词更适合,作者认为)加载的实例,其中动作的实体是最后的定义名为的对象,构造子注入匿名对象,其定义为类为app.dao.EmployeeDaoImpl的实例,前四个对象作为各自担当不同职责的装备对象的定义,并注入到employeedao对象的<advices>列表中以增强其功能。

<object name = "testbeforeadvice" class = "app.advices.TestBeforeAdvice" singleton = "true">

</object>

<object name = "testaroundadvice" class = "app.advices.TestAroundAdvice" singleton = "true">

</object>

<object name = "testafteradvice" class = "app.advices.TestAfterAdvice" singleton = "true">

</object>

<object name = "testthrowsadvice" class = "app.advices.TestThrowsAdvice" singleton = "true">

</object>

 

<object name = "employeedao" class = "ProxyObjectHandler">

<constructor>

<arg class = "app.dao.EmployeeDaoImpl"/>

</constructor>

<advices>

<element object = "testbeforeadvice" />

<element object = "testaroundadvice" />

<element object = "testafteradvice" />

<element object = "testthrowsadvice" />

</advices>

</object>

五、接口Handler拦截器的定义,下述对象前者为Handler对象,后者以标签<interruptor>装配此对象实现应用扩展。

<object name = "testhandler" class = "app.advices.TestHandler" singleton = "true">

</object>

<object name = "empbohandler" class = "app.bo.HrBOImpl" singleton = "true">

<constructor>

<arg object = "employeedao" >

</arg>

</constructor>

<interruptor object = "testhandler">

</interruptor>

</object>

 

 

下面给出Framework的类组织结构图(排得有点乱,还望各位见谅):

 

 

 

其中IoC容器采用工厂、桥接与单件模式以明确操作目的,分为IBeansFactory接口与其功能实现类BeansFactory,从图中可以看出,其直接依赖于类XMLCommon与类Reflection以及接口IProxyBeansFactory。其中系统对XML文件的访问则依据类XMLCommon定义为单件对象,系统对象的动态构造与克隆均由反射对象Reflection来完成,亦采用单件模式来限定该对象。接口IProxyBeansFactory及其实现类ProxyBeansFactory顾名思义代理对象工厂,用于完成其传入对象的深加工,以便其能够装备更强的功能,其加工的结果则为传入对象的代理实例。

对于AOP部分,IProxyInterfacehandler可单独作用亦可与IAdvice二者共同结合发挥功效,其中前者处理对目标对象的代理封装,后者则为该目标对象的各个行为加入切入点以达到监视与增强其功能的目的,并且一个目标对象可以配置多个装备,本框架中模拟Spring预设了几个装备如下图所示。

 

这里仿照Spring命名,但有所区别,IBeforeAdvice装备是在接口方法运行前切入运行,IAfterAdvice则在接口方法运行后转入执行,IAroundAdvice则同时用前置与后置切入点将接口方法包围,IThrowsAdvice则专门用于接口方法的异常拦截处理。

关于实体与装备,借助轻量级的IoC框架,他们之间不直接产生耦合,并且可以按需加载和卸载,所以处理变得极为灵活。打个比方,就是一堆零件的规格型号以及他们之间的关系(依赖、聚合等)订制到XML文件中,一车间(IBeansFactory)将他们装备成一功能集合体如一辆坦克,再送往二车间(IProxyBeansFactory)深加工,增强其机动性能、火炮精度等机能,然后再送往一车间(IBeansFactory)进行其它处理。

当然IoC所遵循的是按需分配的原则,即需要的时候组装。所以如果不对这些对象进行收集管理,则系统很多的资源都会浪费在对象的创建过程中,因此设置对象缓冲并实现非单件对象的克隆可以减少因频繁文档读取创建对象带来的性能损失,本框架中对象克隆没有找到更为合适处理方法,因为没能查到JAVA是否提供了类似于C的内存管理函数,所以只有采用反射来完成缓冲对象的克隆处理,后面会陆续解释相关实现.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值