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理论提出的观点思想是这样的:借助于“第三方”实现具有依赖关系对象之间的解耦。
大家发现了吧,由于引进了第三方的IoC容器,是的A、B、C、D这4个对象之间没有了耦合关系,对象之间的依赖关系完全交给了Ioc容器。所以,IoC容器成了整个系统的核心,它起到了一种“粘合剂”的作用,把系统中的所有对象粘合在一起。
我们来做个试验,把上图中的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等。
如下图所示
3、Spring的入门案例
建立一个基于Maven的Spring IoC项目,以Idea 和 maven创建的一个普通的Java项目为例。
3.1 创建项目(Maven)
此处不选取任何模板,只是创建一个Java项目
这样一个Maven的spring对象就创建好了。
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>
閱讀更多 大數據漫路求索 的文章