Spring(一): 入门



Spring框架简介

Spring 的源码及文档下载,点击这里
Spring 框架第一个版本发布于 2004 年,自发布以来已历经三个主要版本更新:
Spring 2.0 提供了 XML 命名空间和 AspectJ 支持;
Spring 2.5 增加了注释驱动(annotation-driven)的配置支持;
Spring 3.0增加了对 Java 5+ 版本的支持和 @Configuration 模型;
Spring 4.0 是最新的主要版本,并且首次完全支持 Java 8 的特性。 你仍然可以使用老版本的 Java,但是最低版本的要求已经提高到 Java SE 6
Spring Framework 的功能被组织成了20来个模块。
以Spring4.x为例,官方的框架图如下:

Spring框架

我画的模块之间的依赖关系如下(绿色为springframework的模块):

Spring模块

Core Container

Core Containerspring-core, spring-beans, spring-context, spring-context-supportspring-expression (Spring Expression Language) 模块组成

  • spring-corespring-beans 提供框架的基础部分,包括 IoCDependency Injection 主要组件是BeanFactory,它 是一个复杂的工厂模式的实现。
  • Context(spring-context) 模块建立在CoreBeans 模块的基础上,向 Spring 框架提供上下文信息。 ApplicationContext 是 Context 模块的焦点。spring-context-support 对常见第三方库集成进Spring应用上下文提供支持。
  • SpEL(spring-expression) 模块提供了一个强大的 Expression Language(表达式语言)用来在运行时查询和操作对象映射。这是JSP2.1规范所指定的统一表达式语言(unified EL)的一种延续。

AOP、Aspects、Instrumentation、Messaging

  • spring-aop 模块提供 AOP Alliance-compliant(AOP联盟)的面向切面编程实现,允许你自定义,比如,方法拦截器和切入点完全分离代码。
  • spring-aspects 模块提供了集成使用 AspectJ。
  • spring-instrument 模块提供了对某些应用程序服务器的代理接口。
  • spring-messaging 模块从 Spring 集成项目中抽象出来,比如 Message, MessageChannel, MessageHandler 及其他用来提供基于消息的基础服务。该模块还包括一组消息映射方法的注解。

Data Access/Integration 数据访问/集成

Data Access/Integration 层由 JDBC, ORM, OXM, JMSTransaction 模块组成。

  • spring-jdbc 模块提供了不需要编写冗长的JDBC代码和解析数据库厂商特有的错误代码的JDBC抽象层。
  • spring-tx 模块支持可编程和声明式事务管理,用于实现特殊的接口和你所有的POJO类(Plain Old Java Objects)。
  • spring-orm 模块提供了流行的 object-relational mapping(对象-关系映射)API,其包含JPA,JDO,Hibernate
  • spring-oxm 模块提供了抽象层用于支持Object/XML mapping(对象/XML映射)的实现,如JAXB、Castor、XMLBeans、JiBXXStream等。
  • spring-jms 模块(Java Messaging Service)包含生产和消费信息的功能。 从 Spring Framework 4.1 开始提供集成 spring-messaging 模块。

Web

Web 层由 spring-web, spring-webmvc, spring-websocketspring-webmvc-portlet组成。

  • spring-web 模块提供了基本的面向web开发的集成功能,例如多方文件上传、使用Servlet listeners以及Web开发应用程序上下文初始化IoC容器等,也包含HTTP客户端以及Spring远程访问的web相关部分。
  • spring-webmvc 模块(也被称为Web Servlet模块)包含Spring的model-view-controller(模型-视图-控制器(MVC))和REST Web Services实现的Web应用程序,并且集成了Spring Framework所有的其他功能。
  • spring-webmvc-portlet 模块(也被称为Web-Portlet模块)使用一个Portlet的环境和spring-webmvc模块功能的镜像提供了MVC模式的实现。

Test

  • spring-test 模块支持通过组合JUnit或TestNG来进行单元测试和集成测试。它提供了连续加载的ApplicationContext并且缓存这些上下文。它还提供了mock object(模仿对象),可以隔离测试代码。

控制反转(IoC)和依赖注入

控制反转(Inversion of Control)和依赖注入(Dependency Injection)意思差不多。当某个实例(调用者)需要调用另一个实例(被调用者)时,之前是通过调用者来创建被调用者的实例(new一个实例),现在创建被调用者的工作交给Spring的容器来完成,称为“控制反转”。 我们描述创建被调用者的方式,由IoC容器来创建管理对象,然后注入到调用者中去,这就是“依赖注入“。注入的方式有通过JavaBean属性(setter方法)注入和通过构造方法注入。

面向方面编程(AOP)

面向方面的编程,即 AOP(Aspect Oriented Programming),是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为进行模块化(例如日志和事务管理)。AOP 的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。 AOP 和 IOC 是补充性的技术,它们都运用模块化方式解决企业应用程序开发中的复杂问题。在典型的面向对象开发方式中,可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是 Java 类不需要知道日志服务的存在,也不需要考虑相关的代码。所以,用 Spring AOP 编写的应用程序代码是松散耦合的。 AOP 的功能完全集成到了 Spring 事务管理、日志和其他各种特性的上下文中。


Spring简单项目示例

BeanFactory是 Spring 作为 IOC 容器核心接口,ApplicationContextBeanFactory的扩展,功能得到了进一步增强。
下面是一个简单的Spring的例子 目录结构如下:

    src
    |--com.test.spring
    |  |--dao
    |  |  |--impl
    |  |  |  |--HelloImpl.java
    |  |  |--Hello.java
    |  |--service
    |  |  |--impl
    |  |  |  |--HelloServiceImpl.java
    |  |  |--HelloService.java
    |  |--TestSpring.java
    resources
    |--spring.xml

源文件内容如下:

// Hello.java
public interface Hello {
    public void sayHello();
}

// HelloImpl.java
public class HelloImpl implements Hello{
    public void sayHello(){
        System.out.println("Hello!");
    }
}

// HelloService.java
public interface HelloService {
    public void testHello();
}

// HelloServiceImpl.java
public class HelloServiceImpl implements HelloService{
    private Hello hello;
    // setter 方法必须写,否则无法注入
    public void setHello(Hello hello) {
        this.hello = hello;
    }
    @Override
    public void testHello() {
        hello.sayHello();
    }
}

//TestSpring.java
public class TestSpring {
    public static void main(String[] args) {
        // 读取 classpath 下面的配置文件,实例化容器
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

        // 这里的字符串是配置文件中通过id指定的
        Hello hello =context.getBean("hello", HelloImpl.class);
//        Hello hello = (Hello) context.getBean("helloImpl");
        hello.sayHello();

        // 注入到HelloServiceImpl 中的 hello 属性中
        HelloService helloService = context.getBean("helloService", HelloService.class);
        helloService.testHello();
    }
}

配置文件spring.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:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="hello" class="com.test.spring.dao.impl.HelloImpl"></bean>
    <bean id="helloService" class="com.test.spring.service.impl.HelloServiceImpl">
        <property name="hello" ref="hello"/>
    </bean>
</beans>