一个轻量级的J2EE开发框架
方便解耦,简化开发; 支持AOP编程;方便进行测试; 方便和其他框架进行整合; 方便进行事务操作; 降低API开发难度
其主要作用为连接应用程序的不同组件提供技术衔接。
开发和部署EJB是个繁琐的过程,虽然使用EJB可以轻松地分发组件,但开发和部署组件后进行难以进行单元测试。应用程序接口API复杂,复杂性远大于好处。
难以进行单元测试。需要通过很多不必要的方法实现多个接口。异常处理冗长且繁琐。部署描述极其不便。主要原因:
简化了单元测试-采用了依赖注入减少了衔接代码架构灵活性与时俱进早期的EJB难以进行单元测试,唯一方法是将其部署到容器中。 Spring Framework采用了依赖注入(DI),可以轻松的用Mock对象取代依赖关系,进而完成单元测试,无需部署整个程序。 简化单元测试有诸多好处:
提高程序员的工作效率能更早发现缺陷,降低修复缺陷的成本应用程序将自动进行单元测试(可在持续集成模式下运行),防止将来出现缺陷在Spring Framework推出之前,典型的JavaEE应用程序会包含大量的衔接代码,例如,获取数据库连接的代码,异常处理代码,事物管理代码,日志记录代码等。 预编译语句(Prepared Statement)示例:
PreparedStatement st=null; try{ st=conn.prepareStatement(INSERT_TODO_QUERY); st.setString(1,bean.getDescription()); st.setBoolean(2,bean.isDone()); st.execute(); } catch(SQLException e){ logger.error("Failed:"+INSERT_TODO_QUERY,e); }finally{ if(st!=null){ try{ st.close(); }catch(SQLException e){ //忽略--没有操作 } } }这里一共4行业务逻辑和超过10行的衔接代码。 SpringFramework可以通过以下代码实现相同逻辑:
jdbcTemplate.update(INSERT_TODO_QUERY,bean.getDescription(), bean.isDone());如何实现的这种简化: 上例中Spring JDBC将大多数受检异常转化成了未受检异常。查询失败时,除了结束语句和承认事物失败之外,我们能做的事不多。而且不必在每个方法中多执行异常处理,可以进行集中处理,然后使用Spring面向切面编程AOP完成注入。 Spring JDBC不需要创建获取连接(getConnection())、创建预编译语句等衔接代码。而是直接在Spring上下文中创建jdbcTemplate类,然后在需要调用时将其注入数据访问对象(DAO)类中。 类似的Spring JMS、Spring AOP和其他的Spring模块也可以减少衔接代码。
好处:减少重复代码,代码维护更加便捷(集中处理事务和异常(横切关注点)@ControllAdvice),程序员可以更加专注于编写业务逻辑。
Spring Framework采用模块化设计,包含一组建立在核心Spring模块之上的独立模块。大多数是独立的,即可以被单独使用。 具体示例:
WEB层,spring提供了SpringMVC框架,也支持Struts,Vaadin,JSF等任意WEB框架。Spring Beans可以使用较少代码实现业务逻辑,还可以集成EJB。Spring在数据层用Spring JDBC简化了JDBC。同时全面支持任何数据层框架,如JPA、Hibernate或iBatis。可以选择使用Spring AOP实现横切关注点(日志记录,事物处理,安全性),也可以用成熟的AOP实现,如AspectJ。 Spring并不会满足所有需求。 它的核心工作是降低应用程序不同组件之间的耦合度并且使他们可以进行测试。 架构灵活性的具体实现: 全面集成我们选择的框架,不想使用特定框架,可以使用其他框架来替代。Spring为了实现它的模块化和灵活性,不断的在提前实现新技术。 例如: Spring Framework先于JavaEE实现了基于注解的控制器。 还先于JavaEE引入了很多的抽象概念,以将应用程序和具体实现分割开来。例如缓存API等等。 另一个重要特性是提供了一系列Spring项目。 例如: Spring Batch定义了一种新方法来构建Java Batch应用程序。而Java EE7发布才制定了相关的批处理应用规范。 架构逐渐向云和微服务进化。SpringCloud可以帮助简化微服务开发和部署,Spring Cloud Data Flow为微服务应用程序提供了业务流程。
Spring Framework高度模块化,提供了20多个模块,而且这些模块都有明确定义的边界。
一般在普通的java项目中,如果需要使用spring来实现对象的调用,需要将以上四个包的依赖都进行导入和部署(即放在lib中,然后在文件架构中导入为artifact)。然后在xml文件中写bean,来调用需要对象的类。最后在测试的地方使用上下文调取xml文件,最后再使用getbean函数调用对应类型的对象。