1,简介:

  IoC :Inverse of control 控制反转 ,思想就是在项目中引入一个工厂容器,对项目中接口依赖对象的创建,实现项目中对于依赖对象解耦合。

  将程序中对象的创建权以及对象的整个生命周期(创建、初始化、销毁),交给工厂容器来管理,而我们不用关心怎么去创建对象(new对象),只需要关注操作对象即可。

2,Spring实例化对象的三种方式:

  1,默认无参构造器创建

  2,静态工厂方法创建

  3,实例工厂方法创建

无参构造器创建:

applicationContext.cml配置:

<?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="bean1" class="com.zy.IoC.Bean1"></bean>
</beans>

JavaBean类 Bean1:

public class Bean1 {
public Bean1() {
System.out.println("Bean1的无参构造方法");
}
}

测试:

    @Test
public void createObjByConstructor() {
//获取spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//从容器中获取对象
Bean1 bean1 = ac.getBean("bean1", Bean1.class);
System.out.println("******************************");
System.out.println(bean1);
}

运行结果:

静态工厂方法创建:

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"> <!--无参构造器-->
<bean id="bean1" class="com.zy.IoC.Bean1"></bean>
<!--静态工厂方法-->
<bean id="bean2" class="com.zy.IoC.Bean2Factory" factory-method="getBean2"></bean>
</beans>

JavaBean类 Bean2:

public class Bean2 {
public Bean2() {
System.out.println("Bean2的无参构造方法");
}
}

静态工厂:

public class Bean2Factory {
public Bean2Factory() {
System.out.println("Bean2Factory 的构造方法");
} public static Bean2 getBean2(){
return new Bean2();
}
}

测试:

    @Test
public void createObjByStaticFactory() {
//获取spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取对象
Bean2 bean2 = ac.getBean("bean2", Bean2.class);
System.out.println("******************************");
System.out.println(bean2);
}

运行结果:

实例工厂方法创建:

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"> <!--无参构造器-->
<bean id="bean1" class="com.zy.IoC.Bean1"></bean>
<!--静态工厂方法-->
<bean id="bean2" class="com.zy.IoC.Bean2Factory" factory-method="getBean2"></bean>
<!--实例化工厂方法-->
<bean id="bean3Factory" class="com.zy.IoC.Bean3Factory"></bean>
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
</beans>

JavaBean类 Bean3:

public class Bean3 {
public Bean3() {
System.out.println("Bean3的无参构造方法");
}
}

工厂:

public class Bean3Factory {
public Bean3Factory() {
System.out.println("Bean3Factory 的构造方法");
} public Bean3 getBean3(){
return new Bean3();
}
}

测试:

    @Test
public void createObjByFactory() {
//获取spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取对象
Bean3 bean3 = ac.getBean("bean3", Bean3.class);
System.out.println("******************************");
System.out.println(bean3);
}

运行结果:

其实除了以上三种方法以外还有一种方法就是我们自己写一个工厂类来实现FactoryBean接口:

实现FactoryBean接口:

<?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或者name 是对象的唯一标识 class配置对象的全路径-->
<bean id="userDao" class="com.zy.dao.impl.UserDaoImpl2"></bean>
<bean id="userService" lazy-init="true" class="com.zy.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean> <!--无参构造器-->
<bean id="bean1" class="com.zy.IoC.Bean1" lazy-init="true"></bean>
<!--静态工厂方法-->
<bean id="bean2" class="com.zy.IoC.Bean2Factory" factory-method="getBean2"></bean>
<!--实例化工厂方法-->
<bean id="bean3Factory" class="com.zy.IoC.Bean3Factory"></bean>
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean> <!--自己创建工厂(实现FactoryBean接口)-->
<bean id="bean3_2" class="com.zy.IoC.MyFactoryBean"></bean>
</beans>

自己创建的工厂:

public class MyFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
//这里返回实例
return new Bean3();
} @Override
public Class<?> getObjectType() {
return null;
} @Override
public boolean isSingleton() {
return false;
}
}

测试及运行结果大家可以自己实现以下,这里就不多做讲述了。

可以看出以上方法都可以把对象创建出来,但是会有一个问题 不知道大家有没有发现,就是每次获取spring容器的时候,都会创建一个新的spring容器,而且这个容器在被创建的时候会把所有写在配置文件中的对象都创建出来,你用的时候 再根据需要把对应的对象给你,那么这种方式是不可取的,那么现在给大家介绍一下lazy-init来解决这个问题,其实还有更好的解决方案,这个我们以后的文章里再说。

3,配置中的一些其他属性:

lazy-init:(懒加载,容器创建对象的时机配置)

现在我们把我们的applicationContext.xml文件的配置写成这样的(无参构造器的bean配置里把lazy-init=“true”):

<?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="bean1" class="com.zy.IoC.Bean1" lazy-init="true"></bean>
<!--静态工厂方法-->
<bean id="bean2" class="com.zy.IoC.Bean2Factory" factory-method="getBean2"></bean>
<!--实例化工厂方法-->
<bean id="bean3Factory" class="com.zy.IoC.Bean3Factory"></bean>
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
</beans>

运行测试实例化工厂方法的test方法得出如下结果:

会发现Bean1的无参构造方法没有被调用,也就是说我们使用了lazy-init懒加载以后,Bean1的构造在不被调用的时候 是不会加载的。

Scope:(Bean的作用域配置)

既然说过了lazy-init是懒加载,那就有必要再说一下设置Bean的作用域的scope,scope的值有以下几种,默认为第一个singleton:

重点为singleton和prototype:

  1. singleton 单实例(一个容器中只有一个实例, 默认作用域)

  2. prototype 原型 多实例 (每次getBean都会返回 一个新的实例 )

实例如下:

// 单例
public class SingletonBean {
public SingletonBean() {
System.out.println("单实例Bean SingletonBean 初始化...");
}
}
// 多实例
public class PrototypeBean {
public PrototypeBean() {
System.out.println("多实例bean PrototypeBean 初始化 ...");
}
}

配置:

    <!-- ========================================= c_scope bean的作用域 -->
<!-- 如果不指定scope属性,默认就是单实例 -->
<bean id="singletonBean" class="com.zy.spring.SingletonBean" />
<bean id="prototypeBean" class="com.zy.spring.PrototypeBean" scope="prototype"/>

测试:

    @Test
public void testScope() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 单例
SingletonBean singletonBean1 = (SingletonBean) applicationContext
.getBean("singletonBean");
SingletonBean singletonBean2 = (SingletonBean) applicationContext
.getBean("singletonBean");
System.out.println(singletonBean1);
System.out.println(singletonBean2); // 多例
PrototypeBean prototypeBean1 = (PrototypeBean) applicationContext
.getBean("prototypeBean");
PrototypeBean prototypeBean2 = (PrototypeBean) applicationContext
.getBean("prototypeBean");
System.out.println(prototypeBean1);
System.out.println(prototypeBean2);
}

运行结果,很明显单实例的只被初始化了一次,后面每次拿到的都是引用,多实例是每次都初始化一次:

4,Spring容器的生命周期

JavaBean类:

public class SpringLifeCycle {
//构造方法
public SpringLifeCycle() {
System.out.println("SpringLifeCycle 构造...");
}
//初始化方法
public void init() {
System.out.println("SpringLifeCycle 初始化...");
}
//销毁方法
public void destroy() {
System.out.println("SpringLifeCycle 销毁...");
} public void helloSpring() {
System.out.println("hello spring !");
}
}

Bean的初始化,销毁属性配置:(init-method初始化方法,destroy-method销毁方法)

<bean id="springLifecycle" class="com.zy.spring.SpringLifeCycle" init-method="init" destroy-method="destroy" />

测试:

    @Test
public void testScope() {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"applicationContext.xml");
SpringLifeCycle springLifeCycle = (SpringLifeCycle) ac.getBean("springLifeCycle");
springLifeCycle.helloSpring(); // 调用close(ApplicationContext没有close方法,需要转子类调用close)
ClassPathXmlApplicationContext classAc = (ClassPathXmlApplicationContext) ac;
classAc.close();
}

运行结果:

Spring总结二:IOC(控制反转)xml方式的更多相关文章

  1. Spring学习之Ioc控制反转(1)

    开始之前: 1. 本博文为原创,转载请注明出处 2. 作者非计算机科班出身,如有错误,请多指正 ---------------------------------------------------- ...

  2. Spring学习之Ioc控制反转(2)

    开始之前: 1. 本博文为原创,转载请注明出处 2. 作者非计算机科班出身,如有错误,请多指正 ---------------------------------------------------- ...

  3. Spring框架之IOC(控制反转)

    [TOC] 第一章Spring框架简介 IOC(控制反转)和AOP(面向方面编程)作为Spring框架的两个核心,很好地实现了解耦合.所以,简单来说,Spring是一个轻量级的控制反转(IoC)和面向 ...

  4. Spring框架中IoC(控制反转)的原理(转)

    原文链接:Spring框架中IoC(控制反转)的原理 一.IoC的基础知识以及原理: 1.IoC理论的背景:在采用面向对象方法设计的软件系统中,底层实现都是由N个对象组成的,所有的对象通过彼此的合作, ...

  5. Spring源码——IOC控制反转

    1.基础知识 Spring有两个核心功能,分别是ioc和aop,其中ioc是控制反转,aop是切面编程. 在ioc中,还有一个名次叫DI,也就是依赖注入.嗯,好像IOC和DI是指同一个,好像又感觉他俩 ...

  6. Spring 什么是 IOC 控制反转 ?什么是依赖注入?spring的用处 好处 为什么要用

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha Spring是一个开源的控制反转(Inversion of Control ,IoC)和 ...

  7. Spring第一课:IOC控制反转,什么是反转,什么又是控制?

    前言 学习Spring第一课,就是认识IOC控制反转,要了解它还真得花一些功夫.今天主要理解透彻它的真谛,而不仅限于表面. 上道小菜 public class BusinessService { pr ...

  8. 一) Spring 介绍、IOC控制反转思想与DI依赖注入

    一.spring介绍1.IOC反转控制思想(Inversion of Control)与DI依赖注入(Dependency Injection)2.AOP面向切面的编程思想与动态代理3.作用:项目的粘 ...

  9. Spring中的IoC(控制反转)具体是什么东西

    IOC:inverse of Control: 控制反转. 意思是程序中的之间的关系,不用代码控制,而完全是由容器来控制.在运行阶段,容器会根据配置信息直接把他们的关系注入到组件中.同样,这也是 依赖 ...

  10. 零基础带你看Spring源码——IOC控制反转

    本章开始来学习下Spring的源码,看看Spring框架最核心.最常用的功能是怎么实现的. 网上介绍Spring,说源码的文章,大多数都是生搬硬推,都是直接看来的观点换个描述就放出来.这并不能说有问题 ...

随机推荐

  1. Lua学习---编译生成lua和luac

    众所周知,Lua是一种强大的脚本语言,并且这种语言是用C语言实现的.为什么要学习这门语言?因为它可以增强我看C语言代码的功底. 我下的Lua版本是Lua5.3,关于Lua5.3的简介如下: http: ...

  2. 对结合BDD进行DDD开发的一点思考和整理

    引言 二十年前的我,还在学校里抱着一台DIY机(德州486+大众主板+16M内存+3.5inch软驱+昆腾320M硬盘,当时全校最快主机没有之一),揣着一本<Undocumented DOS&g ...

  3. [转载] ffmpeg摄像头视频采集-采集步骤概述并采集一帧视频

    近期由于工作任务,需要开发一个跨平台视频聊天系统,其中就用到了ffmpeg进行采集与编码,网上找了一大堆的资料,虽然都有一些有用的东西,但实在太碎片化了,这几天一直在整理和实验这些资料,边整理,边做一 ...

  4. 剑指offer-第六章面试中的各项能力(数组中只出现一次的数字)

    题目:输入一个数组,该数组中有两个只出现一次的数字,其他的数字都出现两次,输出出只出现一次的数字. 思路:首先,我们可以将这个数组分成两份,一份里面放一个只出现一次的数字.那么我们该怎么分呢?将整个数 ...

  5. rpm -Uvh 升级时的陷阱

    问题现象 用rpm -Uvh升级后,原先的一个软链接被删除了,而采用先rpm -e 卸载rpm包,再rpm -ivh 安装包的方法,这个软链接还在.这个软链接是在rpm包安装的时候建立,也只有在rpm ...

  6. lvs之 lvs+nginx+tomcat_1、tomcat_2+redis(lvs dr 模式)

    前提:已经安装好 lvs+nginx+tomcat_1.tomcat_2+redis环境 ,可参考 (略有改动,比如tomcat_1.tomcat_2安装在两台机器上,而不是单机多实例 ,自行稍稍变动 ...

  7. (转)java中查找List的快捷小方法

    相信java开发的程序员,经常会遍历list里的数据,来查找想要的数据.之后选出来在做处理,我这有个小方法在大量数据的情况下能更快捷,当然这方法只对菜鸟有点用,对老鸟来说也许有更好的方法,请指点 遍历 ...

  8. JMeter启动时显示Could not open/create prefs root node Software\JavaSoft\Prefs at root 0X80000002

    在windows 7上启动jmeter时,提示错误: Java.util.prefs.WindowsPreferences <init> WARNING: Could not open/c ...

  9. 新机器连接老机器遇到的ERROR

    Ansible无法连接老旧机器 报错内容: [root@BI ansible]# ansible -i /etc/ansible/hosts GameServer -m ping 10.10.113. ...

  10. C 游戏所要看的书

    C 游戏所要看的书 1.C++primer中文版第4版     经典啊2.C++标准程序库自修教程与参考手册 3.Windows程序设计第5版 4.MFC windows程序设计第2版中文版 5.VC ...