第一章 Spring Framework概述

Spring Framework 相比较EJB是一个轻量级的解决方案,是构建企业级应用的一站式解决方案。同时Spring 是模块化的,允许您只使用您需要的那部分,而无需引入其余的。您可以在任何 web 框架中引入 IoC 容器,并且您也可以只使用Hibernate或者JDBC。Spring Framework 支持声明式的事务管理 (transaction management),通过 RMI 或 web services 远程访问您的逻辑,以及用于保存数据的各种选项。它提供MVC架构,并且使您能够将AOP透明地集成到您的软件中。

Spring 被设计为非侵入式的,这意味着你的逻辑代码通常不依赖于框架本身。在 integration 层(例如数据访问层)中,存在对数据访问技术和 Spring libraries 的一些依赖。然而,从代码中分离这些依赖是很容易。


1、Spring Framework 简介

Spring Framework是一个java平台,为开发java应用程序提供全面的基础架构支持。由于spring已经提供了基础架构,因此你只需要专注于应用开发。


1.1、控制反转和依赖注入

使用面向对象编程的系统中,它的底层都是有N个对象来组成实现的,所有的对象通过彼此之间的合作,最终实现系统的业务逻辑。

随着业务系统的不断壮大,对象之间的依赖关系也越来越复杂,经常会出现对象之间的多重依赖性关系,对象之间耦合度越高的系统,必然会出现牵一发而动全身的情况。

如何降低系统之间、模块之间和对象之间的耦合度,是软件工程领域永远追求的目标之一。软件转件Michael Mattson提出了控制反转(IoC)理论,用来实现对象之间的“解耦”,目前很多J2EE项目都采用了Spring的IoC技术。


1.2、什么是控制反转(IoC)

IoC是Inversion of Control的缩写,可以翻译成“控制反转”或者“反转控制”。IoC理论提出的观点思想是这样的:借助于“第三方”实现具有依赖关系对象之间的解耦。

第一章 Spring Framework概述

IoC解耦过程

大家发现了吧,由于引进了第三方的IoC容器,是的A、B、C、D这4个对象之间没有了耦合关系,对象之间的依赖关系完全交给了Ioc容器。所以,IoC容器成了整个系统的核心,它起到了一种“粘合剂”的作用,把系统中的所有对象粘合在一起。

我们来做个试验,把上图中的IoC容器拿掉,整个系统会变成这个样子:

第一章 Spring Framework概述

去掉IoC容器后的系统

这时候,A、B、C、D这4个对象之间已经没有了耦合关系,彼此毫无联系,这样的话,当你在实现A对象逻辑的时候,根本不用去考虑B、C和D了,对象之间的依赖关系已经降低到最低水平。因此,如果使用了IoC容器,对于做系统来说,是一件非常美好的事情,参与开发的工程师只需要关注自己的实现类即可,跟别人没有任何关系!

我们再来回顾一下IoC的原理,通俗的讲一下:

  • 在没有引入IoC容器之前,如果对象A依赖于对象B,那么对象A在初始化或者运行到某一个功能的时候,自己必须要主动创建对象B或者是使用以前已经创建的对象B。无论是创建还是使用对象B,主动权都在自己的手里。
  • 在引入IoC容器之后呢,对象A和对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IoC容器会主动创建一个对象B注入到对象A需要的地方。

通过前后的对比,我们不难看出:对象A获得依赖对象B的过程,由主动行为变成了被动行为,控制权颠倒过来了,这就是控制反转(IoC)的含义。

1.3、IoC的应用

IoC是一种思想,它不是一种编程技术,它能够指导我们如何设计出低耦合的程序。传统的应用程序都是由我们在类的内部主动创建对象,从而导致类与类之间高耦合,不利进行测试;有了IoC容器之后,把创建和查找控制对象的权限交给了容器,由容器进行注入组合对象,因此,对象与对象之间是 低耦合的。这种结构设计,有利于功能的复用,而且能够使整个程序的体系结构变得非常灵活。

IoC对于编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序变得被动 了,被动的等待IoC容器来创建并注入它所需要的资源。


1.4、DI(依赖注入),IoC的别名

2004年,Martin Fowler探讨了同一个问题,既然IoC是控制反转,那么它到底“哪方面被控制反转了呢?”,经过不断的分析和探讨之后,他得出的结论是“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了有IoC容器主动注入。于是,他给“控制反转”取了一个更合适的名字“依赖注入(Dependency Injection)”。他的结论,实际上给出了IoC的方法:注入。所谓依赖注入,就是由IoC容器在运行期间,动态的将某种依赖关系注入到对象之中。

所以,依赖注入(DI)和控制反转(IoC)只是从不同的角度来描述同一个事情,就是指通过引入IoC容器,利用依赖注入的方式,实现对象之间的解耦。

2、Spring Framework的体系结构

Spring Framework大概由20个模块组成,这些模块包括:Core Container,Data Access/Injection,Web,AOP(Aspect Oriented Programming),Instrumentation,Messaging和Test等。

如下图所示

第一章 Spring Framework概述

Spring Framework 架构

3、Spring的入门案例

建立一个基于Maven的Spring IoC项目,以Idea 和 maven创建的一个普通的Java项目为例。

3.1 创建项目(Maven)


第一章 Spring Framework概述

此处不选取任何模板,只是创建一个Java项目

第一章 Spring Framework概述


第一章 Spring Framework概述

这样一个Maven的spring对象就创建好了。


第一章 Spring Framework概述

3.2 导入Pom.xml依赖包

<code>
<project>         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelversion>4.0.0/<modelversion>

   <groupid>org.example/<groupid>
   <artifactid>learning-spring01/<artifactid>
   <version>1.0-SNAPSHOT/<version>

   
   <properties>
       <project.build.sourceencoding>UTF-8/<project.build.sourceencoding>
       <java.version>1.8/<java.version>
       <junit.version>4.12/<junit.version>
       <spring-framework.version>4.3.18.RELEASE/<spring-framework.version>
       <log4j.version>1.2.17/<log4j.version>
   /<properties>

   
   <dependencies>
       
       <dependency>
           <groupid>org.springframework/<groupid>
           <artifactid>spring-context/<artifactid>
           <version>${spring-framework.version}/<version>
       /<dependency>

       
       <dependency>
           <groupid>log4j/<groupid>
           <artifactid>log4j/<artifactid>
           <version>${log4j.version}/<version>
       /<dependency>

       <dependency>
           <groupid>org.springframework/<groupid>
           <artifactid>spring-test/<artifactid>
           <version>${spring-framework.version}/<version>
           <scope>test/<scope>

       /<dependency>
       <dependency>
           <groupid>junit/<groupid>
           <artifactid>junit/<artifactid>
           <version>${junit.version}/<version>
           <scope>compile/<scope>
       /<dependency>
   /<dependencies>


   
   <build>
       <plugins>
           <plugin>
               <groupid>org.apache.maven.plugins/<groupid>
               <artifactid>maven-compiler-plugin/<artifactid>
               <version>3.8.0/<version>
               <executions>
                   <execution>
                       compile
                       <phase>compile/<phase>
                       <goals>
                           <goal>compile/<goal>
                       /<goals>
                   /<execution>
                   <execution>
                       testCompile
                       <phase>test-compile/<phase>
                       <goals>
                           <goal>testCompile/<goal>
                       /<goals>
                   /<execution>
               /<executions>
               <configuration>
                   <source>${java.version}/<source>
                   <target>${java.version}/<target>
               /<configuration>
           /<plugin>
       /<plugins>
   /<build>
/<project>/<code>


3.3 创建对象

目标:使用spring创建对象,为属性赋值


Student.java

<code>package com.bigdata.bean;

public class Student {
   private String stuId;
   private String stuName;
   private Integer age;

   public String getStuId() {
       return stuId;
  }

   public void setStuId(String stuId) {
       this.stuId = stuId;
  }

   public String getStuName() {
       return stuName;
  }

   public void setStuName(String stuName) {
       this.stuName = stuName;
  }

   public Integer getAge() {
       return age;
  }

   public void setAge(Integer age) {
       this.age = age;
  }

   @Override
   public String toString() {
       return "Student{" +
               "stuId='" + stuId + '\\'' +
               ", stuName='" + stuName + '\\'' +
               ", age=" + age +
               '}';
  }
}

​/<code>


3.4 编写配置文件,将对象注册到容器中

配置文件的名字和路径都可以任意,建议resources/applicationContext.xml

导入约束

<code>
<beans>       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      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/context http://www.springframework.org/schema/context/spring-context.xsd">

   
   
   
   <bean>
       
       <property>
       <property>
       <property>
   /<bean>
/<beans>/<code>


3.5 配置log4j.properties

<code>log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c]- %m%n

log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c]- %m%n/<code>

3.6 测试,通过Spring的IOC容器创建Student类实例

<code>package com.bigdata.ioc.test;

import com.bigdata.bean.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class IoCTest {

   // 1.创建IOC容器对象
   ApplicationContext bean = new ClassPathXmlApplicationContext("applicationContext.xml");

   @Test
   public void testIoCBean() {

       //2.根据id值获取bean实例对象
       Student student = (Student)bean.getBean("student");

       //3.打印Bean
       System.out.println(student);
  }
}
​/<code>


第一章 Spring Framework概述



分享到:


相關文章: