首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

利用aop复建数据访问层

2012-10-09 
利用aop重构数据访问层由于一直以来小项目做的多,造成了轻后端重前端的恶果,结果后端现在还在使用陈旧的js

利用aop重构数据访问层

由于一直以来小项目做的多,造成了轻后端重前端的恶果,结果后端现在还在使用陈旧的jsp,数据访问层重复代码也不少,近来看了下 spring in action决定对这一部分进行一些修改


1。原先架构


每个模块一个类,层层继承,形成模块功能链

public class Module {    public void actionA(){}    public void actionC(){}.....}public class ModuleA extend Module{      public void actionA(){            Connection con=DB.getConnection();            try{            }catch(....){              logger.error(...);            }finally{                  con.close();            }      }      //other actions}public class ModuleB  extends ModuleA{      public void actionB(){      }      //other actions }

?调用时,只需调用ModuleB的操作(继承最低层功能类,包含所有操作),

?

Module getModule() {   return new ModuleB();}getModule().action..(...);
?

?

一方面connection处理在各个方法冗余,另一方面那么当新增加模块时,有两个选择


1.三处源代码修改

public class Module {   //added action}public class ModuleC  extends ModuleB{      public void actionC(){      }      //other actions }Module getModule() {   return new ModuleC();}

2.还是三处源代码修改

public class Module {   //added action}public class ModuleB  extends ModuleC{      public void actionB(){      }      //other actions }public class ModuleC  extends ModuleA{      public void actionC(){      }      //other actions }

即关键为维护链状继承结构。


2.利用aop重构

利用spring的aop特性将connection创建过程抽离出来,利用aop前置将connection先创建出来保存在模块中,后置销毁成员变量connection。

?

1.首先修改基类,将连接做为成员变量:

public class Module {    private Connection con;    public void setConnection(Connection con){this.con=con;}    public Connection getConnection(){return this.con;}    public void actionA(){}    // .. other actions}

?

其他模块数据库操作改变

?

public class ModuleA extends Module{      public void actionA(){            Connection con=this.getConnection();            //.. 数据库操作            //不用关闭,不用处理异常      }      //other action}


在各个模块的操作中,不用关闭连接,也不用处理异常,将这些功能切面独立出来


2.创建 aspect

?

2.1 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-2.0.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"><bean id="Op"  scope="prototype"/><bean id="DbOp" /><aop:config><aop:aspect ref="DbOp"><aop:pointcut id="DbOpPointcut"expression="execution(* Module*.action*(..)) and target(bean)" /><aop:before method="prepareConnection" pointcut-ref="DbOpPointcut"arg-names="bean" /><aop:after-returning method="closeConnection"pointcut-ref="DbOpPointcut" arg-names="bean" /><aop:after-throwing method="exceptionHandle"pointcut-ref="DbOpPointcut" arg-names="bean" /></aop:aspect></aop:config></beans>

其中Op指向继承最低层的模块对象(包含所有模块操作),对 Module*类的action*方法创建pointcut,并且给advise传递target参数,即module功能对象。


2.2 aspect

public class DbOp {static Logger logger = Logger.getLogger(DbOp.class);public void prepareConnection(Module impl) throws SQLException {Connection con = null;con =DB.getConnection();impl.setConnection(con);logger.info("prepareConnection");}public void closeConnection(Module impl) throws SQLException {Connection con = impl.getConnection();con.close();con = null;impl.setConnection(con);logger.info("closeConnection");}public void exceptionHandle(Module impl) {Connection con = impl.getConnection();if (con != null) {try {con.close();} catch (SQLException e) {e.printStackTrace();}con = null;impl.setConnection(con);}logger.info("exceptionHandle");}}
?

将创建连接,销毁连接,异常处理分离开,并将连接保存到模块功能对象即可。


3.最后改变获取模块功能对象的方式

?

ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");Module getModule(){    return (Module)ctx.get("Op");}
?

这样的话以后添加新的模块,只需更改两处源码:

?

public class Module {   //added action}public class ModuleC  extends ModuleB{      public void actionB(){      }      //other actions }

?

以及一处xml配置即可:

?

<bean id="Op"  scope="prototype"/>


且代码更清晰易懂。

?

?

1 楼 hanqunfeng 2010-02-27   既然用了spring,为什么不直接使用数据库模板类来处理dao层。

热点排行