`
yiminghe
  • 浏览: 1466697 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

利用aop重构数据访问层

    博客分类:
  • java
阅读更多

由于一直以来小项目做的多,造成了轻后端重前端的恶果,结果后端现在还在使用陈旧的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" class="ModuleB"  scope="prototype"/>
	
	<bean id="DbOp" class="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" class="ModuleC"  scope="prototype"/>


且代码更清晰易懂。

 

 

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

相关推荐

    cps重构技术方案

    - STParkRecordDao:停车场记录数据访问对象接口,定义了数据访问层的方法。 - STParkRecordServiceImpl:停车场记录服务实现,提供了具体的数据访问实现。 重构方案还包括了定时任务、模型包和配置文件的使用: -...

    springmvc重构员工管理系统

    4. **Service层**:在员工管理系统中,Service层是业务逻辑层,通常与DAO层(数据访问对象)交互,处理数据操作。可以使用Spring的依赖注入(DI)功能将Service实例注入到Controller中。 5. **Repository/DAO接口**...

    项目重构方案设计(1).pdf

    8. **构建项目结构**:根据实际需求,构建层次化的项目结构,例如采用MVVM模式,调整UI结构,使得UI、服务层、业务逻辑层和数据访问层各自明确职责。 9. **客户特定需求**:由于客户要求不引用第三方组件,因此很多...

    基于SSM框架的商场订单管理系统平台.rar

    此外,项目的三层架构通常指的是表现层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。表现层负责用户界面和交互,业务逻辑层处理业务规则和数据验证,数据访问层...

    稍微用SSH重构当当网

    它将业务逻辑、表示层和数据访问分离开来,提高了代码的可维护性和可重用性。Struts通过Action和ActionForm类处理HTTP请求,并通过配置文件定义请求与Action之间的映射。 3. **Hibernate**:Hibernate是一个强大的...

    SSMJ0006.rar

    这个阶段性的重构可能涵盖了多个技术层面,包括但不限于架构优化、模块拆分、数据访问层改进等。 标签中提到了"struts"、"spring"、"mybatis"和"jquery",这四个关键词是Java Web开发中非常关键的技术栈: 1. **...

    SPRING ,HIBERNATE,MYBATIS重构系统

    MyBatis则是一个轻量级的持久层框架,它将SQL语句与Java代码相结合,提供了灵活的数据访问。 首先,让我们深入了解Spring框架。Spring框架的核心是IoC(Inversion of Control)和AOP(Aspect Oriented Programming...

    Ibatis.net框架和Spring.Net框架的实例代码

    在IT行业中,开发高效、可维护的软件系统是至关重要的,而Ibatis.net和Spring.Net框架就是这样的工具,它们能够帮助开发者实现数据访问层的高效管理。本文将深入探讨这两个框架,并结合提供的"IbatisNetTest"文件名...

    ASP.NET MVC Spring.Net NHibernate整合源码.

    开发者可以通过分析这些代码,了解如何在 ASP.NET MVC 中配置和使用 Spring.Net 的依赖注入,以及如何利用 NHibernate 实现数据访问层的功能。 在这个源码中,你可以学习到: 1. 如何设置 ASP.NET MVC 项目结构和...

    ssm学习记录二

    在SSM项目中,MyBatis作为数据访问层,负责与数据库交互,将Java对象与数据库表之间的映射关系进行配置,并执行SQL查询、插入、更新和删除操作。 4. **集成与配置**:将这三个组件集成在一起,需要配置Spring的...

    JAVA办公自动化系统(源代码+论文+外文翻译)

    Java办公自动化系统通常采用三层架构设计:表现层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。表现层负责用户界面展示,业务逻辑层处理业务规则,而数据访问层...

    达达ASP.NET企业信息管理系统(Spring.NET修改版) 源码_ Visual Studio2008 C#

    它们是业务逻辑和数据访问层之间的桥梁,确保了数据的一致性和完整性。 最后,"SpringResource"可能是Spring.NET的配置文件,包括XML配置和可能的代码注解。这些配置定义了对象的生命周期、依赖关系以及AOP方面的...

    spring4.0 jar包

    5. **数据访问增强**:Spring Data项目在4.0版本中继续发展,增强了对各种数据存储(如JPA、MongoDB、Neo4j等)的支持,简化了数据访问层的代码编写。 6. **RESTful服务**:Spring MVC在4.0版本中对RESTful服务的...

    idea下spring+hibernate模块

    在这个项目中,Spring可能已经被配置为管理Bean的生命周期,以及处理服务层和数据访问层的交互。 Hibernate是一个对象关系映射(ORM)框架,它允许开发者用Java对象来操作数据库,避免了直接编写SQL语句。Hibernate...

    Java毕业设计——基于ssm框架的大学社团管理系统(源码+sql)

    在本系统中,MyBatis作为数据访问层,与数据库进行交互,执行增删改查操作,将数据存取逻辑与业务逻辑分离。 4. **IntelliJ IDEA**:这是一个集成开发环境,广泛用于Java项目开发。它提供了丰富的代码提示、自动...

    J2EE without EJB书的实例jpetstore源码

    4. **数据访问层**:包括`DAO`接口和实现,负责与数据库交互,通常结合Spring的JDBC模板或者Hibernate、MyBatis等ORM框架。 5. **模型对象**:表示业务实体,如`Product`、`Order`等,它们封装了数据并提供了一些...

    spring源码经典实例

    这个项目由Spring创始人Rod Johnson创建,用于展示Spring框架的核心功能,如依赖注入、AOP(面向切面编程)、数据访问以及Web MVC等。在本文中,我们将深入探讨jpetstore项目,了解其背后的Spring框架原理,以及如何...

    nhibernate+spring.net+mvc3.0项目

    在本项目中,NHibernate可能被用来管理数据访问层,简化数据库操作,提高代码的可维护性和可测试性。 **Spring.NET** Spring.NET是.NET平台上一个全面的轻量级应用框架,它借鉴了Java的Spring框架。Spring.NET提供...

    人力资源管理系统

    在该系统中,Hibernate作为数据访问层,自动处理SQL语句的生成和执行,使得开发人员可以专注于业务逻辑,而无需关心底层数据库的具体操作。 【SQL Server数据库】:Microsoft SQL Server是一款关系型数据库管理系统...

    JSP基于SSM民宿预订管理系统可升级SpringBoot源码案例设计.zip

    4. MVC分层设计:业务逻辑层、数据访问层、表现层分离,提高代码可读性和可维护性。 四、升级至SpringBoot SpringBoot简化了SSM的配置,自动配置特性使得开发者可以快速启动项目。升级步骤包括: 1. 引入SpringBoot...

Global site tag (gtag.js) - Google Analytics