首先想说说IoC(Inversion of Control,控制反转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来讲,就是由spring来负责控制对象的生命周期和对象间的关系。这是什么意思呢,举个简单的例子,咱们是如何找女友的?常见的状况是,咱们处处去看哪里有长得漂亮身材又好的mm,而后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,而后嘿嘿……这个过程是复杂深奥的,咱们必须本身设计和面对每一个环节。传统的程序开发也是如此,在一个对象中,若是要使用另外的对象,就必须获得它(本身new一个,或者从JNDI中查询一个),使用完以后还要将对象销毁(好比Connection等),对象始终会和其余的接口或类藕合起来。java
那么IoC是如何作的呢?有点像经过婚介找女友,在我和女友之间引入了一个第三者:婚姻介绍所。婚介管理了不少男男女女的资料,我能够向婚介提出一个列表,告诉它我想找个什么样的女友,好比长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,而后婚介就会按照咱们的要求,提供一个mm,咱们只须要去和她谈恋爱、结婚就好了。简单明了,若是婚介给咱们的人选不符合要求,咱们就会抛出异常。整个过程再也不由我本身控制,而是有婚介这样一个相似容器的机构来控制。Spring所倡导的开发方式就是如此,全部的类都会在spring容器中登记,告诉spring你是个什么东西,你须要什么东西,而后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其余须要你的东西。全部的类的建立、销毁都由 spring来控制,也就是说控制对象生存周期的再也不是引用它的对象,而是spring。对于某个具体的对象而言,之前是它控制其余对象,如今是全部对象都被spring控制,因此这叫控制反转。web
IoC的一个重点是在系统运行中,动态的向某个对象提供它所须要的其余对象。这一点是经过DI(Dependency Injection,依赖注入)来实现的。好比对象A须要操做数据库,之前咱们老是要在A中本身编写代码来得到一个Connection对象,有了 spring咱们就只须要告诉spring,A中须要一个Connection,至于这个Connection怎么构造,什么时候构造,A不须要知道。在系统运行时,spring会在适当的时候制造一个Connection,而后像打针同样,注射到A当中,这样就完成了对各个对象之间关系的控制。A须要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3以后一个重要特征是反射(reflection),它容许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是经过反射来实现注入的。spring
理解了IoC和DI的概念后,一切都将变得简单明了,剩下的工做只是在spring的框架中堆积木而已。数据库
用图例说明一下,传统程序设计如图1-1,都是主动去建立相关对象而后再组合起来:浏览器
图1-1 传统应用程序示意图app
当有了IoC/DI的容器后,在客户端类中再也不主动去建立这些对象了,如图1-2所示:框架
图1-2有IoC/DI容器后程序结构示意图测试
拍电影你们都知道,须要编剧,导演,演员,摄影师。就拿《大话西游》这部电影来举例把。this
编剧(写代码的程序猿):编剧在编写剧本的时候,是不知道剧本中的至尊宝和紫霞仙子的演员是谁的。也就是说编剧只关注个人剧本中的角色以及剧情,不关心这些角色由谁来扮演。spa
导演(spring容器):导演须要负责演员的挑选以及其余工做。
演员(被管理的对象): 演员有不少,刘德华啊,张学友啊,周星驰什么的。
摄影师(模拟程序运行):按照剧本和选择的演员,拍摄电影。
spring的控制反转:导演,就充当着spring容器的做用,前来应聘的演员都在导演这里登记,由导演来管理(如spring管理对象的生命周期,对象的建立和销毁)。假如如今刘德华,张学友,周星驰都想应聘《大话西游》,导演会录入他们的我的信息并登记。也就是说,电影中角色扮演者是由导演一手控制。编剧和摄像师不须要考虑谁来演这个问题,只须要管好本身的事情。(解耦)
spring的依赖注入: 编剧方面,在演员没有肯定好以前,剧本中的人物都是虚幻的,没有实例化的,也就是还没法开拍(程序没法运行,由于有些依赖没有到位),但这并不影响编剧写剧本。spring的依赖注入,在电影这个例子中能够解释为-在导演肯定好演员,编剧写好剧本后,就该正式开拍了。拍摄是按照剧原本的,剧本中的人物又须要现实的明星来表演,这里就要用到依赖注入了。好比剧本中至尊宝带金刚圈的剧情,拍摄时须要人来演至尊宝,就找导演要人(找spring要合适的对象),导演已经肯定了周星驰比较适合演至尊宝,就直接把周星驰扔给他们。
目录结构:
Person类,表示人(演员都是人)。有get,set方法。
person类有一个say(String str)的方法,就是人说话。(模拟演员说台词)
package com.sicau.test; /** * Person * create by chenshihang on 2018/10/26 */ public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void say(String str){ System.out.println(this.getName()+"口音:"+str); } }
TestController类。用来测试
这个类能够看做是编剧,写剧本。能够看到,这段剧本须要两个Person,一个角色是自尊包,一个角色是紫霞。(但编剧并不关心具体演员是谁)
package com.sicau.controller; import com.sicau.test.A; import com.sicau.test.Person; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; /** * TestController * create by chenshihang on 2018/10/24 */ @Controller public class TestController { @Autowired//默认是经过type匹配 @Qualifier("zhizunbao")//结合该注解,能够经过name去匹配 private Person zhizunbao; @Autowired @Qualifier("zixia") private Person zixia; @RequestMapping("/toTest1.form") public String Test1(){ System.out.println("toTest1"); zhizunbao.say("hehe"); zixia.say("haha"); return "test"; } }
spring容器核心配置文件 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" 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"> <context:component-scan base-package="com.sicau.*"/> <bean id="zhizunbao" class="com.sicau.test.Person"> <property name="age" value="1"/> <property name="name" value="z周星驰"/> </bean> <bean id="zixia" class="com.sicau.test.Person"> <property name="age" value="12"/> <property name="name" value="朱茵"/> </bean> </beans>
当程序运行时(拍摄时)
浏览器访问:
进入编剧写好的剧本Test1
导演将周星驰和朱茵扔给摄影师,周星驰和朱茵就充当了至尊宝和紫霞
正式表演,剧本中至尊宝说hehe,紫霞说haha(程序运行)
控制台打印出信息: