第一节: spring IoC 的详解
首先想说说 IoC(Inversion of Control, 控制倒转). 这是 spring 的核心, 贯穿始终. 所谓 IoC, 对于 spring 框架来说, 就是由 spring 来负责控制对象的生命周期和对象间的关系. 这是什么意思呢, 举个简单的例子, 我们是如何找女朋友的? 常见的情况是, 我们到处去看哪里有长得漂亮身材又好的 mm, 然后打听她们的兴趣爱好, qq 号, 电话号, ip 号, iq 号........., 想办法认识她们, 投其所好送其所要, 然后嘿嘿...... 这个过程是复杂深奥的, 我们必须自己设计和面对每个环节. 传统的程序开发也是如此, 在一个对象中, 如果要使用另外的对象, 就必须得到它 (自己 new 一个, 或者从 JNDI 中查询一个), 使用完之后还要将对象销毁 (比 Connection 等), 对象始终会和其他的接口或类藕合起来.
那么 IoC 是如何做的呢? 有点像通过婚介找女朋友, 在我和女朋友之间引入了一个第三者: 婚姻介绍所. 婚介管理了很多男男女女的资料, 我可以向婚介提出一个列表, 告诉它我想找个什么样的女朋友, 比如长得像李嘉欣, 身材像林熙雷, 唱歌像周杰伦, 速度像卡洛斯, 技术像齐达内之类的, 然后婚介就会按照我们的要求, 提供一个 mm, 我们只需要去和她谈恋爱, 结婚就行了. 简单明了, 如果婚介给我们的人选不符合要求, 我们就会抛出异常. 整个过程不再由我自己控制, 而是有婚介这样一个类似容器的机构来控制.
Spring 所倡导的开发方式就是如此, 所有的类都会在 spring 容器中登记, 告诉 spring 你是个什么东西, 你需要什么东西, 然后 spring 会在系统运行到适当的时候, 把你要的东西主动给你, 同时也把你交给其他需要你的东西. 所有的类的创建, 销毁都由 spring 来控制, 也就是说控制对象生存周期的不再是引用它的对象, 而是 spring. 对于某个具体的对象而言, 以前是它控制其他对象, 现在是所有对象都被 spring 控制, 所以这叫控制反转.
IoC 的一个重点是在系统运行中, 动态的向某个对象提供它所需要的其他对象. 这一点是通过 DI(Dependency Injection, 依赖注入) 来实现的. 比如对象 A 需要操作数据库, 以前我们总是要在 A 中自己编写代码来获得一个 Connection 对象, 有了 spring 我们就只需要告诉 spring,A 中需要一个 Connection, 至于这个 Connection 怎么构造, 何时构造, A 不需要知道. 在系统运行时, spring 会在适当的时候制造一个 Connection, 然后像打针一样, 注射到 A 当中, 这样就完成了对各个对象之间关系的控制. A 需要依赖 Connection 才能正常运行, 而这个 Connection 是由 spring 注入到 A 中的, 依赖注入的名字就这么来的.
第二节 小例子
有一个测试工作, 张三测试时候要 new 一个张三, 李四测试的时候要 new 一个李四, 这是一种强耦合, 不好.
- package o1.test;
- /**
- * @author nidegui
- * @create 2019-06-22 11:36
- */
- public class JavaWord {
- public static void main(String[] args) {
- //Lisi lisi=new Lisi();
- Zhangsan zhangsan=new Zhangsan();
- zhangsan.test();
- }
- }
- package o1.test;
- /**
- * @author nidegui
- * @create 2019-06-22 11:35
- */
- public class Lisi {
- public void test(){
- System.out.println("李四做测试");
- }
- }
- package o1.test;
- /**
- * @author nidegui
- * @create 2019-06-22 11:34
- */
- public class Zhangsan {
- public void test(){
- System.out.println("张三做测试");
- }
- }
现在, 改进了设计方式, 将控制权交给 spring 来管理, 控制权移交出去.
- package com.java.test2;
- /**
- * @author nidegui
- * @create 2019-06-22 11:43
- */
- public interface Tester {
- public void test();
- }
- package com.java.test2;
- /**
- * @author nidegui
- * @create 2019-06-22 11:35
- */
- public class Lisi implements Tester {
- public void test(){
- System.out.println("李四做测试");
- }
- }
- package com.java.test2;
- /**
- * @author nidegui
- * @create 2019-06-22 11:34
- */
- public class Zhangsan implements Tester {
- public void test(){
- System.out.println("张三做测试");
- }
- }
- package com.java.test2;
- /**
- * @author nidegui
- * @create 2019-06-22 11:36
- */
- public class JavaWord {
- private Tester tester;
- public void setTester(Tester tester) {
- this.tester = tester;
- }
- public void test(){
- tester.test();
- }
- }
- <?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">
- <bean id="lisi" class="com.java.test2.Lisi"></bean>
- <bean id="zhangsan" class="com.java.test2.Zhangsan"></bean>
- <bean id="work" class="com.java.test2.JavaWord">
- <property name="tester" ref="lisi"></property> <!-- 这个属性的 name 要对应 -->
- </bean>
- </beans>
- package com.java.test2;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- /**
- * @author nidegui
- * @create 2019-06-22 11:53
- */
- public class Test {
- public static void main(String[] args) {
- ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
- JavaWord JavaWord =(JavaWord) ac.getBean("work");
- JavaWord.test();
- }
- }
来源: http://www.bubuko.com/infodetail-3100189.html