Spring框架简介

2011-12-26  来源:本站原创  分类:java基础  人气:2 

1、使用框架的意义与Spring的主要内容

随着软件结构的日益庞大,软件模块化趋势出现,软件开发也需要多人合作,随即分工出现。如何划分模块,如何定义接口方便分工成为软件工程设计中越来越关注的问题。良好的模块化具有以下优势:可扩展、易验证、易维护、易分工、易理解、代码复用。

优良的模块设计往往遵守“低耦合高内聚”的原则。而“框架”是对开发中良好设计的总结,把设计中经常使用的代码独立出来,所形成的一种软件工具。用户遵守它的开发规则,就可以实现良好的模块化,避免软件开发中潜在的问题。广义上的框架无处不再,一个常见的例子就是PC硬件体系结构,人们只要按照各自需要的主板、显卡、内存等器件就可以任意组装成自己想要的电脑。而做主板的厂商不用关心做显卡厂商的怎么实现它的功能。软件框架也是如此,开发人员只要在Spring框架中填充自己的业务逻辑就能完成一个模块划分清晰纷的系统。

这里主要通过一个银行通知用户月收支记录的小例子来介绍轻型J2EE框架Spring的主要内容、它所解决的问题和实现的方法。

Spring框架主要可以分为3个核心内容:

1、容器

2、控制反转(IoC ,Inversion of Control)

3、面向切面编程(AOP ,Aspect-Oriented Programming)

例子中依次对这些特性进行介绍,描述了软件模块化后存在的依赖与问题,以及Spring框架如何解决这些问题。

2、一个简单的例子程序

假设有一个如下应用场景:(1)一个银行在每月的月初都需要向客户发送上个月的账单,账单发送的方式可以为纸质邮寄、或者短信方式。(2)还有一个潜在的需求:为了安全起见,在每个函数操作过程中都需要记录日志,记录参数传入是否正常,函数是否正常结束,以便出错时系统管理员查账。

那么对这个需求进行简单实现。系统框图如下所示:

Spring框架简介

首先定义一个账单输出的接口:

//接口
public interface ReportGenerator{
    public void generate(String[][] table) ;
}

实现“打印纸质账单”与“发送短信”两个具体功能:

//账单报表实现类
public class PageReportGenerator implement ReportGenerator {
    public void generate(String[][] table) {
        log4j.info( ... );    //输出日志
        ...打印操作,以便工作人员邮递给客户
        log4j.info( ... );    //输出日志
    }
}
//短信报表实现类
public class SMSReportGenerator implement ReportGenerator {
    public void generate(String[][] table) {
        log4j.info( ... );
        ...短信发送操作
        log4j.info( ... );
     }
}

上层业务逻辑对上个月的账目进行统计并调用接口产生纸质或者短信结果:

//上层业务中的服务类
public class ReportService{
    private ReportGenerator reportGenerator = new SMSReportGenerator();
    public void generateMonthlyReport(int year, int month) {
        log4j.info( ... );
        String[][] statistics = null ;
        ...
        reportGenerator.generate(statistics);
    }
}

这个实现源代码请查看文章结尾附录中的"BankOld"。源代码中与例子中程序略有区别:由于使用log4j需要引用外部的包,并且需要写配置文件,为了方便,源代码中的日志输出用system.out.println()代替。

3、Spring中的容器

A、模块化后出现的问题与隐患

假设随着工程的复杂化,上面的例子需要分成两个模块,以便开发时分工,一般会以如下结构划分:

Spring框架简介

划分后再看原来的代码:

//上层业务中的服务类
public class ReportService{
    private ReportGenerator reportGenerator = new SMSReportGenerator(); //隐患 

    public void generateMonthlyReport(int year, int month) {
        ...
    }
}

在服务类有private ReportGenerator reportGenerator = new SMSReportGenerator();这么一行代码,ReportService类与SMSReportGenerator类不属于同一个模块,当开发人员B对内部实现进行修改时,由于存在依赖,开发人员A也要进行修改(比如之前喜欢短信收账单的客户感觉短信不够详细,希望以后改用邮件收账单,那么开发人员B需要实现一个MailReportGenerator类,在开发人员B修改代码时,开发人员A也需要改代码------声明部分修改)。如果系统庞大new
SMSReportGenerator()大量使用的话,修改就会十分复杂,一个声明没有修改就会出现大的BUG。

所以需要一种划分,让各个模块尽可能独立,当开发人员B修改自己的模块时,开发人员A不需要修改任何代码。

B、问题出现的原因

为例子中的程序画一个UML依赖图:

Spring框架简介

可以发现上述问题出现的原因主要是:模块A与模块B不但存在接口依赖,还存在实现依赖。ReportGenerator每次修改它的实现,都会对ReportService产生影响。那么需要重构消除这种实现依赖。

C、用容器解决问题

消除实现依赖一般可以通过添加一个容器类来解决。在例子程序容器代码如下:

//容器类
public class Container { 

    public static Container instance; 

    private Map<String, Object> components; 

    public Container(){
        component = new HashMap<String, Object>();
        instance = this; 

        ReportGenertor reportGenertor = new SMSReportGenertor();
        components.put(“reportGenertor”, reportGenertor); 

        ReportService reportService = new ReportService();
        components.put(“reportService”, reportService);
    } 

    public Object getComponent(String id){
        return components.get(id);
    }
}

使用容器后,模块A的ReportService的属性实现方法也发生了变化。

//服务类变更,降低了耦合
public class ReportService{ 

    //private ReportGenerator reportGenerator = new SMSReportGenerator();
    private ReportGenerator reportGenerator = (ReportGenerator) Container.instance.getComponent(“reportGenerator”); 

    public void generateMonthlyReport(int year, int month) {
        ...
    }
}

这样的话,class都在容器中实现,使用者只需要在容器中查找需要的实例,开发人员修改模块B后(在模块中增加邮件报表生成类MailReportGenerator),只需要在容器类中修改声明(把ReportGenertor
reportGenertor = new SMSReportGenertor();改为ReportGenertor reportGenertor = new
MailReportGenertor();)即可,模块A不需要修改任何代码。一定程度上降低了模块之间的耦合。

4、Spring中的控制反转

A、还存在的耦合

使用容器后模块A与模块B之间的耦合减少了,但是通过UML依赖图可以看出模块A开始依赖于容器类:
Spring框架简介

之前的模块A对模块B的实现依赖通过容器进行传递,在程序中用(ReportGenerator) Container.instance.getComponent(“reportGenerator”)的方法取得容器中SMSReportGenertor的实例,这种用字符(“reportGenerator”)指代具体实现类SMSReportGenertor 的方式并没有完全的解决耦合。所以在银行账单的例子中我们需要消除ReportService对容器Container的依赖。

B、控制反转与依赖注入

在我们常规的思维中,ReportService需要初始化它的属性private ReportGenerator reportGenerator就必须进行主动搜索需要的外部资源。不使用容器时,它需要找到SMSReportGenertor()的构造函数;当使用容器时需要知道SMSReportGenertor实例在容器中的命名。无论怎么封装,这种主动查找外部资源的行为都必须知道如何获得资源,也就是肯定存在一种或强或弱的依赖。那是否存在一种方式,让ReportService不再主动初始化reportGenerator,被动的接受推送的资源?

这种反转资源获取方向的思想被称为控制反转(IoC,Inversion of Control),使用控制反转后,容器主动地将资源推送给需要资源的类(或称为bean)ReportService,而ReportService需要做的只是用一种合适的方式接受资源。控制反转的具体实现过程用到了依赖注入(DI,Dependecncy Injection)的设计模式,ReportService类接受资源的方式有多种,其中一种就是在类中定义一个setter方法,让容器将匹配的资源注入:setter的写法如下:

//为需要依赖注入的类加入一种被称为setter的方法 

public class ReportService{ 

    /*private ReportGenerator reportGenerator =
        (ReportGenerator) Container.instance.getComponent(“reportGenerator”); */ 

    private ReportGenerator reportGenerator; 

    public void setReportGenerator( ReportGenerator reportGenerator) {
        this.reportGenerator = reportGenerator;
    } 

    public void generateMonthlyReport(int year, int month) {
        ...
    }
}

在容器中把依赖注入:

//容器类
public class Container { 

    ...
    public Container ( ) {
        component = new HashMap<String, Object>();
        instance = this;
        ReportGenertor reportGenertor = new SMSReportGenertor();
        components.put(“reportGenertor”, reportGenertor); 

        ReportService reportService = new ReportService();
        reportService.setReportGenerator(reportGenerator); //使用ReportService的setter方法注入依赖关系
        components.put(“reportService”, reportService);
    }
    ...
}

这样一来ReportService就不用管SMSReportGenertor在容器中是什么名字,模块A对于模块B只有接口依赖,做到了松耦合。

C、Spring IoC容器的XML配置

每个使用Spring框架的工程都会用到容器与控制反转,为了代码复用,Spring把通用的代码独立出来形成了自己的IoC容器供开发者使用:

Spring框架简介

与上面例子中实现的容器相比,Spring框架提供的IoC容器要远远复杂的多,但用户不用关心Spring
IoC容器的代码实现,Spring提供了一种简便的bean依赖关系配置方式------使用XML文件,在上面的例子中,配置依赖关系只要在工程根目录下的“application.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:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" >

    <bean id="smsReportGenerator" class="bank.SMSReportGenerator" />

    <bean id="reportService" class="bank.ReportService">
       <property name="reportGenerator" ref="smsReportGenerator" />
    </bean>
 </beans>

<?xml version="1.0" encoding="UTF-8"?>是标准的XML头,xmlns引用的是一些命名空间,两个一般在工程中自动生成。后面的内容由用户输入,主要表示实例化SMSReportGenerator,实例化ReportService并把SMSReportGenerator的对象smsReportGenerator赋值给ReportService的属性reportGenerator,完成依赖注入。

5、Spring中的面向切面编程

A、日志问题以及延伸

在例子的需求中有一条是:需要记录日志,以便出错时系统管理员查账。回顾例子中的代码,在每个方法中都加了日志操作:

//服务类
public class ReportService{
    ...
    public void generateMonthlyReport(int year, int month) {
        log4j.info( ... );   //记录函数的初始状况参数等信息
        String[ ][ ] statistics = null ;
        ...
        reportGenerator.generate(statistics);
        log4j.info( ... );   //记录函数的执行状况与返回值
    }
}

//凭条报表实现类
public class PageReportGenerator implement ReportGenerator { 

    public void generate(String[ ][ ] table) { 

        log4j.info( ... );       //记录函数的初始状况参数等信息
        …打印操作
        log4j.info( ... );       //记录函数的执行状况与返回值
    }
}

可以看出在每个方法的开始与结尾都调用了日志输出,这种零散的日志操作存在着一些隐患,会导致维护的困难。比如日志输出的格式发送了变化,那么无论模块A还是模块B的程序员都要对每个方法每个输出逐条修改,极容易遗漏,造成日志输出风格的不一致。又比如不用Log4j日志输出工具更换其他工具,如果遗漏一个将会出现严重BUG。

与日志输出相似的问题在编程中经常遇到,这种跨越好几个模块的功能和需求被称为横切关注点,典型的有日志、验证、事务管理等。

Spring框架简介

横切关注点容易导致代码混乱、代码分散的问题。而如何将很切关注点模块化是本节的重点。

B、代理模式

传统的面向对象方法很难实现很切关注点的模块化。一般的实现方式是使用设计模式中的代理模式。代理模式的原理是使用一个代理将对象包装起来,这个代理对象就取代了原有对象,任何对原对象的调用都首先经过代理,代理可以完成一些额外的任务,所以代理模式能够实现横切关注点。

Spring框架简介

可能在有些程序中有很多横切关注点,那么只需要在代理外再加几层代理即可。以银行账单为例介绍一个种用Java Reflection API动态代理实现的横切关注点模块化方法。系统提供了一个InvocationHandler接口:

//系统提供的代理接口
public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throw Throwable;
}

我们需要实现这个接口来创建一个日志代理,实现代码如下:

//日志代理实现
public class LogHandler implement InvocationHandler{ 

    private Object target; 

    public LogHandler(Object target){
        this.target = target;
    }
    public Object invoke(Object proxy, Method method, Object[] args ) throw Throwable{ 

        //记录函数的初始状况参数等信息
        log4j.info(“开始:方法”+ method.getName() + “参数”+Arrays.toString(args) );

        Object result = method.invoke(target, args); 

        //记录函数的执行状况与返回值
        log4j.info(“结束:方法”+ method.getName() + “返回值”+ result ); 

    }
 }

这样既可以使得日志操作不再零散分布于各个模块,易于管理。调用者可以通过如下方式调用:

//主函数
public class Main{
    public static void main(String[ ] args){
        ReportGenerator reportGeneratorImpl  = new SMSReportGenerator (); 

        //通过系统提供的Proxy.newProxyInstance创建动态代理实例
        ReportGenerator reportGenerator = (ReportGenerator ) Proxy.newProxyInstance(
            reportGeneratorImpl.getClass().getClassLoader(),
            reportGeneratorImpl.getClass().getInterfaces(),
            new LogHandler(reportGeneratorImpl)
        ) ;
        ...
    }
}

代理模式很好的实现了横切关注点的模块化,解决了代码混乱代码分散问题,但是我们可以看出用 Java Reflection API 实现的动态代理结构十分复杂,不易理解,Spring框架利用了代理模式的思想,提出了一种基于JAVA注解(Annotation)和XML配置的面向切面编程方法(AOP ,Aspect-Oriented Programming)简化了编程过程。

C、Spring AOP 使用方法

Spring AOP使用中需要为横切关注点(有些时候也叫切面)实现一个类,银行账单的例子中,切面的实现如下:

//切面模块实现
@Aspect    //注解1
public class LogAspect{ 

    @Before(“execution(* *.*(..))”)    //注解2
    public void LogBefore(JoinPoint joinPoint)  throw Throwable{
        log4j.info(“开始:方法”+ joinPoint.getSignature().getName() );
    } 

    @After(“execution(* *.*(..))”)     //注解3
    public void LogAfter(JoinPoint joinPoint)  throw Throwable{
        log4j.info(“结束:方法”+ joinPoint.getSignature().getName() );
    }
}

注解1表示这个类是一个切面,注解2中" * *.*(..)* "是一个通配符,表示在容器中所有类里有参数的方法。@Before(“execution(* *.*(..))”)表示在所有类里有参数的方法前调用切面中德 LogBefore() 方法。同理,注解3中@After(“execution(* *.*(..))”)表示在所有类里有参数的方法执行完后调用切面中的LogAfter()方法。
实现完切面类后,还需要对Spring工程中的application.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:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" > 

    <aop:aspectj-autoproxy />
    <bean id="smsReportGenerator" class="bank.SMSReportGenerator" />
    <bean id="reportService" class="bank.ReportService">
        <property name="reportGenerator" ref="smsReportGenerator" />
    </bean>
    <bean class="bank.LogAspect" />
</beans>

这比之前IoC依赖关系配置的XML文件多了:xmlns:aop=http://www.springframework.org/schema/aop;http://www.springframework.org/schema/aop;http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
这3个主要是声明XML中用于AOP的一些标签, <bean class="bank.LogAspect" /> 是在容器中声明LogAspect切面,<aop:aspectj-autoproxy />用于自动关联很切关注点(LogAspect)与核心关注点(SMSReportGenerator,ReportService)。不难发现Spring AOP的方法实现横切关注点得模块化要比用Java Reflection API简单很多。

6、Spring总结

银行月账单报表例子通过使用Spring框架后变成了如下结构:

Spring框架简介

在Spring框架的基础上原来存在耦合的程序被分成松耦合的三个模块。无论那个模块修改,对其他模块不需要额外改动。这就完成了一种良好的架构,使软件易理解,模块分工明确,为软件的扩展、验证、维护、分工提供了良好基础。这就是Spring框架作用。当然Spring除了容器、控制反转、面向切面之外还有许多其他功能,但都是在这三个核心基础上实现的。

通过Spring框架来重构银行月账单例子的源代码在附录的“BankSpring”中。

附件

[1] 例子中不用Spring的实现BankOld源代码

[2] 使用Spring后的实现BankSpring源代码

参考文献

[1] Gary Mak ,《Spring 攻略》

相关文章
  • Spring 框架简介 2011-08-22

    Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架. 在这篇由三部分组成的 Spring 系列 的第 1 部分中,我将介绍 Spring 框架.我先从框架底层模型的角度描述该框架的功能,然后将讨论两个最有趣的模块:Spring 面向方面编程(AOP)和控制反转 (IOC) 容器.接着将使用几个示例演示 IOC 容器在典型应用程序用例场景中的应用情况.这些示例还将成

  • Spring框架简介 2011-12-26

    1.使用框架的意义与Spring的主要内容 随着软件结构的日益庞大,软件模块化趋势出现,软件开发也需要多人合作,随即分工出现.如何划分模块,如何定义接口方便分工成为软件工程设计中越来越关注的问题.良好的模块化具有以下优势:可扩展.易验证.易维护.易分工.易理解.代码复用. 优良的模块设计往往遵守"低耦合高内聚"的原则.而"框架"是对开发中良好设计的总结,把设计中经常使用的代码独立出来,所形成的一种软件工具.用户遵守它的开发规则,就可以实现良好的模块化,避免软件开发中

  • Spring 系列: Spring 框架简介 2013-08-24

    Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架. 在这篇由三部分组成的 Spring 系列 的第 1 部分中,我将介绍 Spring 框架.我先从框架底层模型的角度描述该框架的功能,然后将讨论两个最有趣的模块:Spring 面向方面编程(AOP)和控制反转 (IOC) 容器.接着将使用几个示例演示 IOC 容器在典型应用程序用例场景中的应用情况.这些示例还将成

  • 视频专辑:Spring框架讲解视频 2013-11-17

    专辑:Spring框架讲解视频 简介:郭宏志 Spring框架讲解视频 1 郭宏志 Spring 01 2013-10-26 11:03 | 播放(14) | 评论(0) | 时长:56:40 2 郭宏志 Spring 02 IOC 2013-10-26 11:04 | 播放(7) | 评论(0) | 时长:44:47 3 郭宏志 Spring 03 DI依赖注入 2013-10-26 11:05 | 播放(6) | 评论(0) | 时长:40:03 4 郭宏志 Spring 04 AOP 20

  • 基于Spring框架的Shiro配置方法 2014-04-12

    这篇文章主要介绍了基于Spring框架的Shiro配置方法,需要的朋友可以参考下 一.在web.xml中添加shiro过滤器 <!-- Shiro filter--> <filter> <filter-name>shiroFilter</filter-name> <filter-class> org.springframework.web.filter.DelegatingFilterProxy </filter-class> <

  • 春天来啦:Spring框架概述 2014-08-02

    Spring框架--由来和发展 Spring是java平台上的一个开源应用框架.它的第一个版本是由Rod Johnson写出来的.Rod在他的Expert One-On-One Java EE Design and Development(Java企业应用设计与开发的专家一对一)一书中首次发布了这个框架.该框架也可以移植到.NET的环境下. Spring的框架首次在2003年6月的Apache 2.0的使用许可中发布.第一个具有里程碑意义的版本是2004年3月发布的1.0.2004年9月和200

  • Gearman(分布式任务调度框架) 简介 2014-06-04

    在@hacker101的围脖上看到了这个框架,看了下官网,觉得很适合爬虫.多进程并行处理等任务. 看看官方提供的几个例子: Mass PDF quote email Synchronous Image Resize Shard-Query: a PHP project which uses Net_Gearman to execute queries on horizontally partitioned databases and returns the results. Supports a

  • 基于Spring框架的WebSphere应用开发 2012-03-09

    概览 轻量级的企业应用开发越来越受到广大J2EE应用开发者的追捧,而Spring框架又是轻量级容器的杰出代表.由于Spring的使用日渐广泛,因此已有许多基于WebSphere应用服务器(WAS)的应用采用了Spring框架.本文首先介绍使用Spring开发Web应用的基本问题,然后结合 WebSphere应用服务器,讲述Spring应用如何结合容器提供的服务.文章目的是与大家一起探讨如何更好的采用Spring框架开发基于 WebSphere应用服务器的应用. 1.Spring框架的主要思想描述

  • 实现基于Spring框架应用的权限控制系统(转) 2013-05-09

    前注:当我摸到了通过filter拦截权限,通过AOP拦截方法,通过权限控制菜单的时候,猛然发现这一切的一切已经是别人已经发明好的轮子. 摘 要 Spring框架是一个优秀的多层 J2EE系统框架,Spring本身没有提供对系统的安全性支持.Acegi是基于Spring IOC 和 AOP机制实现的一个安全框架.本文探讨了Acegi安全框架中各部件之间的交互,并通过扩展Acegi 数据库设计来实现基于Spring框架的应用的安全控制方法. 关键词 Spring :Acegi :认证: 授权 引言

  • Spring MVC 简介 2013-07-24

    Spring MVC,即 Spring Model-View-Controller,是一个实现了通用开发模式(模型-视图-控制器)的Web框架,它通过一个DispatcherServlet处理HTTP请求.完成资源映射.递交请求给控制器完成业务逻辑,相应数据则通过Model传递给视图解析器解析为相应的页面或数据流返回给客户端. 这里,我们可以通过Spring官方给出的图示大致了解其内部的工作机制: DispatcherServlet作为前端控制器(Front Controller)过滤所有客户端

  • j2ee项目中在java类中获取 spring框架项目的绝对路径 2013-10-16

    在开发中,我们需要在java类中来获取程序的绝对路径,而java类中是没有request等对象的,这时候可以用以下方法: 在web.xml中加入监听器,用spring框架的 WebAppRootListener类 <listener> <listener-class> org.springframework.web.util.WebAppRootListener </listener-class> </listener> <context-param&

  • spring mvc 简介 (转) 2014-05-19

    资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf SpringMVC核心配置文件示例.rar 作者:赵磊 博客:http://elf8848.iteye.com 目录 一.前言 二.spring mvc 核心类与接口 三.spring mvc 核心流程图 四.spring mvc DispatcherServlet说明 五.spring mvc 父子上下文的说明 六.springMVC-mvc.xml 配置文件片段讲解 七.spring mvc 如何访问到静态的文件,如

  • 学习Spring框架等技术的方向.方法和动机 2015-04-13

    学习Spring框架 最早学习Spring框架是在大二的时候,当时看了几本书,看了一些视频,主要是传智播客的.更多的,还是写代码,单独写Spring的,也有与Struts和Hibernate等框架整合的.很久以来,主要使用了Spring的注入功能和事务管理,其它功能没怎么用到,可能是没有这方面的需求吧.有好几次都想对Spring有个深入的学习,比如把Spring中的全部功能都了解下,学习下Spring的原理.这2件事情,都是半途而废,有一定深入或全面学习,没有坚持下去. 广度与深度 回顾下自己学

  • 将Flex与Spring框架集成 2014-10-15

    随着富Internet应用(RIA)技术的不断成熟,将类似于Adobe Flex这样的RIA应用与健壮的服务器端技术进行集成就变得越来越重要了.Java开发者最喜欢的服务器端框架之一Spring将在这个过程中扮演着重要的角色. RIAvolutionize the Web的Marco Casario解释到他为何建议BlazeDS成为Spring与Flex结合的企业系统时说道:"Spring是一个开源框架,可以让开发人员开发起来 更加轻松.如果使用标准的JEE方式,你需要编写大量无用或者冗余的代码

  • Spring 框架的优点及缺点 2013-08-15

    首先Spring 是一个框架,使用Spring并不代表代码质量的提高,就像盖房子选择用上海的地皮还是北京的地皮一样,房子质量与土地所在的城市无关,与房子的具体设计方案和选料有关. 使用Spring 等框架可以简化很多基础性的工作,配置好后可以方便构建业务应用. 框架使用多了会有局限的感觉,像小鸟被套在笼子里,无法飞出去,虽然在笼子里面吃喝不愁.目前编程的门槛越来越低,诸多开源框架广泛传播,几乎没有什么技术门槛,会配置就会编程,而一个好的DBA对软件性能会有很大提高,软件的核心逻辑最终会转移到对数

  • Python 各种测试框架简介(四):pytest 2014-05-27

    pytest 有时也被称为 py.test,是因为它使用的执行命令是 $ py.test.本文中我们使用 pytest 指代这个测试框架,py.test 特指运行命令. 较于 nose 这里没有使用像前三篇一样(简介-举例-discovery-环境)式的分段展开,是因为 pytest 与 nose 的基本用法极其相似.因此只做一个比较就好了.他俩的区别仅在于 调用测试的命令不同,pytest 用的是 $ py.test 创建测试环境(setup/teardown)的 api 不同 下面使用一个例

  • Spring框架学习(1) 2014-12-06

    1.spring简单介绍 Spring是一个java开源框架 Spring为企业级应用而生.使用Spring可以使简单的JavaBean实现以前只有EJB(EJB是sun的JavaEE服务器端组件模型,设计目标与核心应用是部署分布式应用程序)才能实现的功能 Spring是一个IOC(反转控制)(DI(依赖注入))和AOP容器框架(在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术).

  • LESS CSS 框架简介(转) 2015-01-15

    原文地址:http://www.ibm.com/developerworks/cn/web/1207_zhaoch_lesscss/ 简介 CSS(层叠样式表)是一门历史悠久的标记性语言,同 HTML 一道,被广泛应用于万维网(World Wide Web)中.HTML 主要负责文档结构的定义,CSS 负责文档表现形式或样式的定义. 作为一门标记性语言,CSS 的语法相对简单,对使用者的要求较低,但同时也带来一些问题:CSS 需要书写大量看似没有逻辑的代码,不方便维护及扩展,不利于复用,尤其对于

  • TMTS-iOS框架简介 2013-12-22

    前面的章节中,对iOS的应用特性,以及现有的一些自动化测试框架做了相关的介绍,针对这些特性,我们结合淘宝应用自身的需求,提供了一套支撑iOS应用的功能自动化测试框架. 框架采用的是嵌入式测试思路,在应用的源码中嵌入测试代码,应用初始完成后生成测试对象,由测试对象完成自动化测试. 统一的控件管理.灵活的控件定位.简单的脚本编写是本框架特点. 框架原理: 由于在iOS中当前激活的应用程序只能有一个,所以我们的框架选择的是注入式框架,我们需要将一个测试对象放入到应用程序中,由测试对象来处理测试相关的事

  • 六款值得推荐的android(安卓)开源框架简介 2014-05-23

    同事整理的android(安卓)开源框架,个个都堪称经典.32 个赞! 1.volley 项目地址 https://github.com/smanikandan14/Volley-demo (1) JSON,图像等的异步下载: (2) 网络请求的排序(scheduling) (3) 网络请求的优先级处理 (4) 缓存 (5) 多级别取消请求 (6) 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求) 2.android-async-http 项目地址:https:/