zoukankan      html  css  js  c++  java
  • java 三大框架——spring

    . Spring框架简介(以下这段话可用于面试求职)

    Spring为JavaEE开发提供了一个轻量级的解决方案,主要表现为,

    • IOC(或者叫做DI)的核心机制,提供了bean工厂(Spring容器),降低了业务对象替换的复杂性,提高了组件之间的解耦。
    • AOP的将一些通用任务,如安全、事务、日志等集中进行管理,提高了复用性和管理的便捷性
    • ORM和DAO提供了与第三方持久层框架的良好整合,简化了底层数据访问。
    • 提供了优秀的Web MVC框架。

    可以说Spring是贯穿表现层、业务层、持久层,为javaEE提供一站式解决方案的框架。此外,使用Spring还有如下好处,

    • 低侵入设计,代码污染极低。
    • 基于Spring框架的应用,可以独立于各种应用服务器,实现 write once, run anywhere,
    • Spring可以与第三方框架良好整合(如ORM,DAO等模块与其他框架整合),但同时Spring提供了高度开放性,应用不会被强制依赖Spring,开发者可以自由选择Spring的部分或者全部。

    Spring并不局限于中间层,而是为系统各层都提供了企业级解决方案(例如IOC可以

    使用Spring框架可以带来诸多好处,例如进行数据库事务处理,远程调用,JMS消息处理,JMX操作处理,而这些处理都不需要开发人员直接使用相关API(JDBC, JMX, JMS 等)

    2.Sping架构

    Spring框架是分模块存在,除了最核心的Spring Core Container(即Spring容器)是必要模块之外,其他模块都是可选,视需要而定。

    官方文档Spring4.0的架构图中,包含了20多个子模块,大致可以分为四类 1)核心容器(Core Container) 2)数据访问和集成(Data Access/Integration) 3)Web 4)AOP。

    本质上Spring可以总结为以下七个模块。

    其中常用模块的大致功能如下。

    核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

    Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

    Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能集成到了 Spring 框架中。可以将一些通用任务,如安全、事务、日志等集中进行管理,提高了复用性和管理的便捷性。

    Spring DAO:为JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

    Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

    Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

    Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

     3.环境搭建

    首先需要下载Spring框架 spring-framework-4.0.4.RELEASE-dist,4.0.4版官方地址为 http://repo.springsource.org/libs-release-local/org/springframework/spring/4.0.4.RELEASE/ (如果觉得太慢也可以去国内网站下载)

    此外,还需要下载一个必要组件 commons-logging-1.1.3-bin ,可以在http://commons.apache.org/官网下载也可以在国内网站下载。

    其他诸如log4j之类的并不是必须下载的。

    下载好以上两个压缩包。在workspace下新建一个lib目录作为user library。将Spring压缩包解压之后,将libs目录下的 *RELEASE.jar(共21个)都拷贝到你的workspace下的lib目录;将commons包也解压,将根目录的*.1.3.jar(共3个)都拷贝到lib目录下。

    之后在Eclipse中添加一个user library,添加成功后的效果如下,

    4.简单demo及控制反转(IOC)和依赖注入(DI)简介

    J2EE提倡面向接口编程,Spring也是针对的接口编程,即在代码中只使用规范(即接口),而将真正的实现类配置在文件中,由Spring的配置文件来决定将会使用哪一个实现类,这也叫做控制反转(IOC)或者依赖注入(DI)。

    现在我们假设有这么一个场景, 我们指定一类人去使用一类斧头,不同的人可以使用不同的斧头,当然其效果不一样。

    按照J2EE的建议,首先我们需要定义“人”和“斧头”两个规范,即创建两个接口,

    斧头接口,

    1 package spi;
    2 
    3 public interface Axe {
    4     public String chop();
    5 }

    斧头接口的一个实现,

    复制代码
    1 package spi;
    2 
    3 public class StoneAxe implements Axe { 
    4     public String chop() {
    5         return "石斧砍柴好慢";
    6     }
    7 }
    复制代码

    人接口

    1 package spi;
    2 
    3 public interface Person {
    4     public void useAxe();
    5 }

    人接口的一个实现,

    复制代码
     1 package spi;
     2 
     3 public class Chinese implements Person {
     4     private Axe axe;
     5     public void setAxe(Axe axe) {
     6         this.axe = axe;
     7     }
     8     public void useAxe() {
     9         System.out.println("我打算去砍点柴火");
    10         System.out.println(axe.chop());
    11     }
    12 }
    复制代码

    下面要写一个测试类,使用Person接口的一个实现类的对象,去调用Axe的一个实现类的对象,

    按照传统编程方式,我们一般会写成下面这样,

    复制代码
     1 package spi;
     2 
     3 public class BeanTest {
     4     public static void main(String[] args) {
     5         Chinese p = new Chinese();
     6         StoneAxe axe = new StoneAxe();
     7         p.setAxe(axe);
     8         p.useAxe();
     9     }
    10 }
    复制代码

     重点是第6行和第7行,即Chinese类和StoneAxe类耦合在了java代码中,如果现在需求有变,我们在这里要使用一种新的斧头,即Axe有一个新的实现类SteelAxe,那么就必须修改这里的代码, SteelAxe axe = new SteelAxe(); 这对于代码维护其实并不方便。 对于这个问题,Spring的解决方案是将上面的步骤放在配置文件中,具体实现方法是这样的,

    首先创建一个配置文件,名字自定义即可,

    复制代码
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="http://www.springframework.org/schema/beans
     5         http://www.springframework.org/schema/beans/spring-beans.xsd">
     6     <bean id="chinese" class="spi.Chinese">
     7         <property name="axe" ref="stoneAxe" />
     8     </bean>
     9     <bean id="stoneAxe" class="spi.StoneAxe" />
    10     <bean id="win" class="javax.swing.JFrame" />
    11     <bean id="date" class="java.util.Date" />
    12 </beans>
    复制代码

    可以看到配置文件中定义了上面两个接口的实现类的具体包路径,其中stoneAxe还被定义成了Chinese类的一个属性,

    有了这个配置文件之后,Spring就可以在底层利用java反射,首先创建出两个类对象(Chinese和StoneAxe),接着马上执行对象的setter方法,依据配置文件中各个类的依赖关系去初始化每个对象的属性,而这个过程,正是上面传统编程中的StoneAxe axe = new StoneAxe();p.setAxe(axe);这两部!

    下面看看Spring方式在测试代码中的写法,

    复制代码
     1 package spi;
     2 
     3 import org.springframework.context.ApplicationContext;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 
     6 public class BeanTest {
     7     public static void main(String[] args) {
     8         ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
     9         Person p = ctx.getBean("chinese", Person.class);
    10         p.useAxe();
    11     }
    12 }
    复制代码

    执行结果,

    1 我打算去砍点柴火
    2 石斧砍柴好慢

    可以看到,在测试代码中,完全没有了Chinese和StoneAxe两个类的耦合依赖关系,转而将依赖关系放在了上面的XML文件中,底层通过java反射的方式进行初始化。

    即,将java代码中对象间的依赖关系的控制权交给了Spring配置文件,由Spring来生成对象,并且设置对象间的依赖关系,这就是控制反转(IOC)或者叫依赖注入(DI)。

    Spring自动生成对象(可禁用)和设置依赖关系是最基本的功能。

    Spring的IOC(或DI)机制,极大地降低了组件间的耦合,例如对于上面的需求变更,我们只需要在XML文件中新增一个bean节点,并设置好依赖关系即可,而测试代码不需要任何改变!

    新增Axe的实现类,

    复制代码
    1 package spi;
    2 
    3 public class SteelAxe implements Axe { 
    4     public String chop() {
    5         return "钢斧砍柴好快";
    6     }
    7 }
    复制代码

    修改Spring配置文件,

    复制代码
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="http://www.springframework.org/schema/beans
     5         http://www.springframework.org/schema/beans/spring-beans.xsd">
     6     <bean id="chinese" class="spi.Chinese">
     7         <property name="axe" ref="steelAxe" />
     8     </bean>
     9     <bean id="stoneAxe" class="spi.StoneAxe" />
    10     <bean id="steelAxe" class="spi.SteelAxe" />
    11     <bean id="win" class="javax.swing.JFrame" />
    12     <bean id="date" class="java.util.Date" />
    13 </beans>
    复制代码

    执行测试类结果,

    1 我打算去砍点柴火
    2 钢斧砍柴好快

    5.设值注入和构造注入

    对于依赖注入,有两种方式,一种是设置注入,即上面XML配置文件中设置<property />标签的方式,这种方法本质上是利用反射调用对象的setter方式进行初始化。

    另外,还可以使用构造注入的方式,即在XML配置文件中使用<constructor-arg />标签,不过这种方式要求有对应的构造方法才行。

    对于上面的例子,首先我们要让Chinese类有一个构造方法,

    1     public Chinese(Axe axe) {
    2         this.axe = axe;
    3     }

    接着我们将XML配置文件中的<peroperty>标签用<constructor-arg>标签替换,

    1     <bean id="chinese" class="spi.Chinese">
    2         <!--  <property name="axe" ref="stoneAxe" /> -->
    3         <constructor-arg ref="stoneAxe" />
    4     </bean>

    我们将得到一样的结果,只是实现的方式不一样而已。对于设值注入和构造注入两种方式如何选择呢,

    一般的,如果对依赖关系无需变化地注入,尽量采用构造注入。其他依赖关系的注入则考虑采用设值方式注入。

  • 相关阅读:
    CodeForces 706C Hard problem
    CodeForces 706A Beru-taxi
    CodeForces 706B Interesting drink
    CodeForces 706E Working routine
    CodeForces 706D Vasiliy's Multiset
    CodeForces 703B Mishka and trip
    CodeForces 703C Chris and Road
    POJ 1835 宇航员
    HDU 4907 Task schedule
    HDU 4911 Inversion
  • 原文地址:https://www.cnblogs.com/hewanli/p/12275596.html
Copyright © 2011-2022 走看看