Spring入门

Spring是一个轻量级的Java开发框架,最早由Robd Johnson创建,目的为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题,它是一个分层的JavaSE/EE轻量级开源框架。

Spring简介

Spring框架已集成了20个模块,这些模块分布在核心容器、数据访问/集成层,Web层,AOP,植入模块,消息传输和测试模块中。如图所示

Spring的由来

Spring的目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。是一个分层的JavaSE/EE的开源框架。

Spring的体系结构

Spring开发环境搭建

使用IDEA搭建JavaWeb应用

Spring的下载和目录结构

Spring更新之后官方建议使用Maven下载,对于不使用maven的开发者,可以到官网下载。这里采用的是spring-framework-5.0.2.RELEASE-dist.zip,解压后就可以看到spring所有的结构。

目录中的docs是文档。包含spring的API文档和开发规范,libs目录包含所有的spring的jar包和源码。schema目录包含Spring应用所需要的schema文件。这些文件定义了spring相关配置文件的约束。

对于初学者,在开发Spring应用只需要将4个基本包和commons-logging-1.2.jar复制到Web工程中即可。

4个基础包:spring-corespring-beansspring-contextspring-expression

使用IDEA开发Spring入门程序

  1. 首先导入jar包,创建maven工程,将4个基本包和一个依赖包导入。
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
  1. 创建接口TestDao

Spring解决的是业务逻辑层与其他各层的耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。

package dao;
public interface TestDao {
public void sayHello();
}
  1. 创建接口TestDao的实现类TestDaoImpl
package dao.Impl;
import dao.TestDao;
public class TestDaoImpl implements TestDao {
@Override
public void sayHello() {
System.out.println("Hello Study");
}
}
  1. 创建配置文件applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--将指定类TestDaoImpl配置给Spring,让Spring创建实例-->
<bean id="test" class="dao.Impl.TestDaoImpl"></bean>
</beans>

配置文件的名称可以随意定义,但习惯上命名为applicationContext.xml,有时候命名为beans.xml。

  1. 创建测试类
package test;
import dao.TestDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//初始化Spring容器ApplicationContext,加载配置文件
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
TestDao testDao = (TestDao)app.getBean("test");//test为配置文件中的id。
testDao.sayHello();
}
}

在执行后会在控制台输出打印结果,在上述main方法没有使用new运算符创建实体对象,而是通过Spring容器来获取实体对象。这就是SpringIOC的工作机制。

spring IoC

IoC(控制反转)是Spring框架的基础,也是Spring框架的核心理念。

Spring IoC的基本概念

控制反转(IoC)是一个比较抽象的概念,是Spring框架的核心,用来消减计算机程序的耦合问题,依赖注入(DI)是IoC的另一个说法,只是从不同的角度描述相同的概念。

通过一个实例来解释IoC和DI。当人们需要一件东西时,第一反应就是找东西,例如想吃面包。在没有面包店和有面包店两种情况下,人们会怎么考虑?在没有面包店时,最直观的做法是按照自己的口味自己制作面包,也就是一个面包需要主动制作,然而时至今日,各种网店,实体店盛行,已经没有必要自己制作,想吃面包,去网店或实体店把自己的口味告诉店家,一会就可以吃到面包了,注意,这种方式并没有制作面包,而是由店家制作,但是完全符合自己的口味。

上述的例子包含了控制反转的思想,即把制作面包的主动权交给商家,下面通过面向对象编程思想继续探讨。

当某个对象(调用者)需要调用另一个对象(被调用者),即被依赖对象时,在传统编程方式下,调用者采用new 被调用者方式去创建对象,这种方式会增大调用者与被调用者的耦合性,不利于后期代码的维护。

当Spring框架出现之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系。而不是由调用者的程序代码控制,这样控制权交给了Spring容器,所以控制权发生反转。

在上述的面包实例中,调用者是想吃面包的人,被调用者是面包,Spring容器就是面包店,new是自己制作面包。

从Spring容器角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,相当于为调用者注入它所依赖的实例,这就是Spring的依赖注入。

Spring IoC容器

实现控制反转的是Spring IoC容器,Spring IoC容器的设计主要是BeanFactoryApplicationContext接口。

BeanFactory

BeanFactoryorg.springframework.beans.factory.BeanFactory接口定义,它提供了完整的IoC服务支持,是一个管理Bean的工厂,主要负责初始化各种Bean。BeanFactory接口有多个实现类,其中比较常用的是org.springframework.beans.factory.xml.XmlBeanFactory,该类会根据XML配置文件的定义来装配Bean。

在创建BeanFactory实例时需要提供XML的绝对路径。

package test;
import dao.TestDao;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class Test {
public static void main(String[] args) {
XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(new FileSystemResource("E:\\javaProject\\spring-book\\ch1\\src\\main\\resources\\applicationContext.xml"));
TestDao testDao = (TestDao)xmlBeanFactory.getBean("test");
testDao.sayHello();
}
}

使用BeanFactory实例加载Spring配置文件在实际开发中很少使用。了解即可。

ApplicationContext

ApplicationContext是BeanFactory的子接口,也称为上下应用文,由org.springframework.context.ApplicationContext接口定义,ApplicationContext接口除了包含BeanFactory的所有功能之外,还添加了对国际化,资源访问,事件传播等内容的支持。

创建ApplicationContext接口实例的方法通常有以下3种:

  1. 通过ClassPathXmlApplicationContext创建

ClassPathXmlApplicationContext将从类路径目录(src目录)中寻找指定的配置文件。

package test;

import dao.TestDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test {
public static void main(String[] args) {
//初始化Spring容器ApplicationContext,加载配置文件
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
TestDao testDao = (TestDao)app.getBean("test");//test为配置文件中的id。
testDao.sayHello();
}
}
  1. 通过FileSystemXmlApplicationContext创建

FileSystemXmlApplicationContext将从指定文件的绝对路径寻找xml配置文件,找到并装载完成ApplicationContext的实例化.

package test;
import dao.TestDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//初始化Spring容器ApplicationContext,加载配置文件
ApplicationContext app = new FileSystemXmlApplicationContext("E:\\javaProject\\spring-book\\ch1\\src\\main\\resources\\applicationContext.xml");
TestDao testDao = (TestDao)app.getBean("test");//test为配置文件中的id。
testDao.sayHello();
}
}

采用绝对路径的加载方式将导致程序的灵活性变差,一般不推荐使用。

  1. 通过web服务器实例化ApplicationContext容器

在Web工程中,ApplicationContext容器的实例化工作将交给Web服务器完成。

实例化容器通过写入web.xml文件进行配置,只需要在web.xml添加代码:

<context-param>
<!--将在src下的applicationContext.xml配置文件-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<!--指定以ContextLoaderListener方式启动Spring容器-->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

依赖注入的类型

在Spring中实现IoC容器的方法是依赖注入,依赖注入的作用是在使用Spring框架创建对象时动态地将其所依赖的对象(例如属性值)注入Bean组件中,Spring框架依赖注入有两种方式,一种是使用构造方法注入,另一种是属性的setter方法注入。

使用构造方法注入

Spring框架可以采用Java的反射机制,通过用构造方法完成依赖注入,下面通过应用实例描述构造方法注入.

  1. 创建dao包,并且创建TestDIDao接口和其实现类TestDIDaoImpl
package dao;
public interface TestDIDao {
public void sayHello();
}
package dao.Impl;
import dao.TestDIDao;
public class TestDIDaoImpl implements TestDIDao {
@Override
public void sayHello() {
System.out.println("TestDIDao Hello");
}
}
  1. 创建service包,并且创建TestDIService接口和其实现类TestDIServiceImpl
package service;
public interface TestDIService {
public void sayHello();
}
package service.Impl;
import dao.TestDIDao;
import service.TestDIService;
public class TestDIServiceImpl implements TestDIService {
private TestDIDao testDIDao;
public TestDIServiceImpl(TestDIDao testDIDao){
super();
this.testDIDao=testDIDao;
}
@Override
public void sayHello() {
testDIDao.sayHello();
System.out.println("TestDIService构造方法注入");
}
}
  1. 编写配置文件,在applicationContext.xml中,首先将dao.TestDIDaoImpl类托管给Spring,让Spring为其创建对象,然后将service.TestDIServiceImpl托管给Spring,让Spring创建其对象,同时给构造方法传递参数。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--将指定类TestDIDaoImpl配置给Spring,让Spring为其创建实例-->
<bean id="myTestDIDao" class="dao.Impl.TestDIDaoImpl"/>
<!--使用构造方法注入-->
<bean id="testDIService" class="service.Impl.TestDIServiceImpl">
<!--将myTestDIDao注入到TestDIServiceImpl类的属性的TestDIDao上-->
<constructor-arg index="0" ref="myTestDIDao"/>
</bean>
</beans>

在配置文件中,constructor-arg元素用于定义构造方法的参数,index用于定义参数的位置,ref指定某个实例的引用,如果是常量值(不是引用类型),ref由value代替。

package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.TestDIService;
public class TestDI {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
TestDIService testDIService = (TestDIService)app.getBean("testDIService");
testDIService.sayHello();
}
}

使用属性的setter方法注入

使用setter方法注入是Spring框架最主流的注入方式,它利用JavaBean规范所定义的setter方法来完成注入,灵活且可读性高。对于setter方法注入,Spring框架也是使用Java的反射机制实现的。

  1. 创建接口的实现类TestDIServiceImpl_setter
package service.Impl;
import dao.TestDIDao;
import service.TestDIService;
public class TestDIServiceImpl_setter implements TestDIService {
private TestDIDao testDIDao; public void setTestDIDao(TestDIDao testDIDao) {
this.testDIDao = testDIDao;
}
@Override
public void sayHello() {
testDIDao.sayHello();
System.out.println("setter方法注入");
}
}
  1. 将TestDIServiceImpl_setter托管给Spring
<!--将指定类TestDIDaoImpl配置给Spring,让Spring为其创建实例-->
<bean id="myTestDIDao" class="dao.Impl.TestDIDaoImpl"/>
<!--使用setter方法注入-->
<bean id="testDIService_setter" class="service.Impl.TestDIServiceImpl_setter">
<!--调用setter方法,将myTestDIDao注入到方法的属性中-->
<property name="testDIDao" ref="myTestDIDao"/>
</bean>

property的参数name为属性名,,type为注入的类型,ref是指定的值(配置文件的id)。

  1. 测试setter注入
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.TestDIService;
public class TestDI_setter {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
TestDIService testDIService = (TestDIService)app.getBean("testDIService_setter");
testDIService.sayHello();
}
}

Spring入门及IoC的概念的更多相关文章

  1. Spring入门2. IoC中装配Bean

    Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...

  2. Spring入门1. IoC入门实例

    Spring入门1. IoC入门实例 Reference:Java EE轻量级解决方案——S2SH 前言: 之前学习过关于Spring的一点知识,曾经因为配置出现问题,而总是被迫放弃学习这些框架技术, ...

  3. Spring入门导读——IoC和AOP

    和MyBatis系列不同的是,在正式开始Spring入门时,我们先来了解两个关于Spring核心的概念,IoC(Inverse of Control)控制反转和AOP()面向切面编程. 1.IoC(I ...

  4. Spring入门 (IOC)

    1.实现原理

  5. Spring入门之IOC

    IOC/DI: Spring最核心的灵魂,IOC/DI(控制反转/依赖注入)!,这里一定要理解他,理解这个思想.我会细说什么是IOC/DI.他的思想是什么.它带来了那些好处. 进入正题,先说说什么是i ...

  6. spring入门(Ioc的理解)

    spring对依赖的注入理解可以参考这篇:https://www.cnblogs.com/alltime/p/6729295.html 依赖注入和控制反转 传统的JavaEE程序中,直接在内部new一 ...

  7. Spring入门介绍-IOC(二)

    浅谈IOC IOC(inversion of control)是Spring的核心,贯穿始终.所谓IOC 就是有Spring来控制对象的生命周期和对象间的关系. 传统开发模式:对象之间相互依赖 IOC ...

  8. Spring入门篇——AOP基本概念

    1.什么是AOP及实现方式 什么是AOP AOP:Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 主要 ...

  9. Spring_第一个Spring入门案例IOC

    今天我们来写我们的第一个spring 第一步 建立一个java project 第二步 添加我们的五个jar文件 第三步 在项目中建立一个com.zk.spring包 第四步 建立我们的userser ...

随机推荐

  1. centos 7 让脚本开机运行

    按照网上搜索的文章指导,有三种方式可以实现,个人觉得比较简单的是修改/etc/rc.d/rc.local,添加要开机执行的命令. 修改后,重启,发现要运行的服务没有启动. 搜索发现下面这篇博客解释了原 ...

  2. js上 十二、函数初步-1

    11-1.引入(认识函数) ​ 引入: 说起函数,其实我们并不陌生,在初中数学中我们就接触过函数:例如我们所学的 y = 2X+1 ; 这是一个二元一次方程,也是我们数字中的函数: ​ 当我们每次输入 ...

  3. SQL精华总结索引类型优化SQL优化事务大表优化思维导图❤️

    索引类型 从数据结构角度: B+树索引, hash索引,基于哈希表实现,只有全值匹配才有效.以链表的形式解决冲突.查找速度非常快 O(1) 全文索引,查找的是文本中的关键词,而不是直接比较索引中的值, ...

  4. Spring Cloud Alibaba基础教程-Nacos(一)

    2019快结束,也有很久没写博客了,今天我们来谈谈Nacos,如果对您有帮助,麻烦左上角点个关注 ,谢谢 ! 嘻嘻 今天先写第一篇 文章目录 为什么要使用Nacos Eureka 闭源 Nacos的优 ...

  5. HTC Vive使用WebVR的方法以及启用后头显无画面的解决方法

    1.下载支持WebVR的浏览器. 笔者使用的是HTC Vive,故下载了Firefox的Nightly版本[下载地址]. 2.Nightly 开启WebVR的步骤[引用自Mozilla VR] 1.从 ...

  6. PSO 粒子群算法

    注:本人参考http://www.cnblogs.com/tiandsp/category/348031.html来实现的 算法步骤: 1.首先确定粒子个数与迭代次数. 2.对每个粒子随机初始化位置与 ...

  7. 制作3D小汽车游戏(上)

    之前一段时间家里和公司的事太多,一直没有时间写博客,最近腾出一段时间,看了一遍官方的examples,收货颇多,想整理一点东西出来,又苦于没有好的东西,three写点东西真是太难了.好吧,今天郭先生就 ...

  8. Git简易教程-安装及简单使用

    Git是一种版本控制器,在项目开发中可以用来托管代码 一.下载安装Git 1. Git下载 地址:https://git-scm.com/download/win 2. 安装 检验是否安装成功 电脑桌 ...

  9. python序列(三)列表元素访问与计数

    1.使用下标直接访问列表元素,如果指定下标不存在,则抛出异常. >>> alist[3] 1 >>> alist[3]=5.5 >>> alist ...

  10. eclipse再见,android studio 新手入门教程(一)基本设置

    写在前面: 作为一个刚半只脚踏入android开发的新手,在使用eclipse开发了两个自我感觉不甚成熟的商城类app之后,遇到了一些问题,总结为如下: 代码复用性.findviewById,oncl ...