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. Arcgis for Js之featurelayer实现空间查询和属性查询

    空间查询和属性查询是常用的两种对数据的检索与查询方式,在本节,将讲述Arcgis for Js下如何实现featurelayer的这两种查询方式,先贴图给大家看看: 实现界面 属性查询 空间查询 看完 ...

  2. Angular在render完成之后,执行Js脚本

    AngularJs中,如何在render完成之后,执行Js脚本 app.directive('onFinishRenderFilters', function ($timeout) { return ...

  3. HDU2032 杨辉三角

    解题思路:不要小看这题水题,如果数据类型没有用long long, 当n开为35时,会出现TLE,而且会报非法内存访问,现在还 不理解为什么,若有高手,请不吝赐教. 上代码: #include< ...

  4. 剑指Offer面试题:9.打印1到最大的n位数

    一 题目:打印1到最大的n位数 题目:输入数字n,按顺序打印从1到最大的n位十进制.比如输入3,则打印出1.2.3一直到最大的3位数即999. 二 不考虑大数解法 // 打印从1到最大的n位数 voi ...

  5. CF311B Cats Transport

    题意 Zxr960115 is owner of a large farm. He feeds m cute cats and employs p feeders. There's a straigh ...

  6. browser-sync 服务器使用

    1. 安装 npm install browser-sync or yarn add browser-sync 2. 使用(集成gulp) 备注: gulp 安装使用此处不介绍 默认的端口是3000, ...

  7. #51单片机#蓝牙模块(ATK-SPP-HC06从机串口)的使用方法

    #include <AT89X51.H> #include <intrins.h> // 函数原形定义 #define uchar unsigned char #define ...

  8. AbstractIdleService

    该类有一个startup和shutdown方法,启动此服务或者结束此服务的时候可以调用. Runtime.getRuntime().addShutdownHook(new Thread() {@Ove ...

  9. ELK之kibana的web报错[request] Data too large, data for [<agg [2]>] would be larger than limit of

    http://blog.51cto.com/11819159/1926411 ELK架构:elasticsearch+kibana+filebeat 版本信息: elasticsearch 5.2.1 ...

  10. WebService简单实现

    1. WebService SOAP.WSDL.UDDISOAP(Simple Object Access Protocal,简单对象访问协议),是在分散或在分布式环境中交换信息的简单协议.WSDL( ...