Spring总结二:IOC(控制反转)xml方式
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:
singleton 单实例(一个容器中只有一个实例, 默认作用域)
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方式的更多相关文章
- Spring学习之Ioc控制反转(1)
开始之前: 1. 本博文为原创,转载请注明出处 2. 作者非计算机科班出身,如有错误,请多指正 ---------------------------------------------------- ...
- Spring学习之Ioc控制反转(2)
开始之前: 1. 本博文为原创,转载请注明出处 2. 作者非计算机科班出身,如有错误,请多指正 ---------------------------------------------------- ...
- Spring框架之IOC(控制反转)
[TOC] 第一章Spring框架简介 IOC(控制反转)和AOP(面向方面编程)作为Spring框架的两个核心,很好地实现了解耦合.所以,简单来说,Spring是一个轻量级的控制反转(IoC)和面向 ...
- Spring框架中IoC(控制反转)的原理(转)
原文链接:Spring框架中IoC(控制反转)的原理 一.IoC的基础知识以及原理: 1.IoC理论的背景:在采用面向对象方法设计的软件系统中,底层实现都是由N个对象组成的,所有的对象通过彼此的合作, ...
- Spring源码——IOC控制反转
1.基础知识 Spring有两个核心功能,分别是ioc和aop,其中ioc是控制反转,aop是切面编程. 在ioc中,还有一个名次叫DI,也就是依赖注入.嗯,好像IOC和DI是指同一个,好像又感觉他俩 ...
- Spring 什么是 IOC 控制反转 ?什么是依赖注入?spring的用处 好处 为什么要用
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha Spring是一个开源的控制反转(Inversion of Control ,IoC)和 ...
- Spring第一课:IOC控制反转,什么是反转,什么又是控制?
前言 学习Spring第一课,就是认识IOC控制反转,要了解它还真得花一些功夫.今天主要理解透彻它的真谛,而不仅限于表面. 上道小菜 public class BusinessService { pr ...
- 一) Spring 介绍、IOC控制反转思想与DI依赖注入
一.spring介绍1.IOC反转控制思想(Inversion of Control)与DI依赖注入(Dependency Injection)2.AOP面向切面的编程思想与动态代理3.作用:项目的粘 ...
- Spring中的IoC(控制反转)具体是什么东西
IOC:inverse of Control: 控制反转. 意思是程序中的之间的关系,不用代码控制,而完全是由容器来控制.在运行阶段,容器会根据配置信息直接把他们的关系注入到组件中.同样,这也是 依赖 ...
- 零基础带你看Spring源码——IOC控制反转
本章开始来学习下Spring的源码,看看Spring框架最核心.最常用的功能是怎么实现的. 网上介绍Spring,说源码的文章,大多数都是生搬硬推,都是直接看来的观点换个描述就放出来.这并不能说有问题 ...
随机推荐
- auto_ptr, unique_ptr, shared_ptr and weak_ptr智能指针讲解
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...
- 典型的一次jQuery.validate.js 表单中的验证应用
var validateOption = { onkeyup:false, rules:{ password:{ required:true, remote:{ url:'index.php?app= ...
- 【MFC】vs2013_MFC使用文件之15.mfc 按钮CBitmapButton的使用
本文是基于对话框的 博文基于 无幻 的博文为基础写的 http://blog.csdn.net/akof1314/article/details/4951836 笔者使用mfc撑死2个星期,不过这是有 ...
- mysql-jdbc创建Statement与执行SQL
使用JDBC创建Connection后,执行SQL需要先创建Statement Statement stmt = connection.createStatement(); 创建代码如下 public ...
- 该文档举例说明了multimap的查找和删除元素的使用
该文档举例说明了multimap的查找和删除元素的使用. 其中,在使用迭代器遍历元素的时候,如果使用了删除迭代器的操作,那么需要小心迭代器失效的情况. /* 功能说明: multimap的查找和删除元 ...
- win10环境变量的配置
c盘->环境变量: 1.添加变量名和变量值 变量名:JAVA_HOME 变量值:C:\Program Files\Java\jdk1.8.0_161 2.添加变量名和变量值 变量名:JAVA_H ...
- Spring3.x JSR-303
JSR303介绍 JSR303-Bean Validation描述:This JSR will define a meta-data model and API for JavaBeanTM vali ...
- runtime获取对象所有属性(变量)和方法
1.包含运行时头文件 <objc/runtime.h> 2.获取某个类的成员变量或者属性: unsigned int numIvars; //成员变量个数 Ivar *vars = cla ...
- web 模板引擎
baiduTemplate: http://baidufe.github.io/BaiduTemplate/ artTemplate: https://github.com/aui/artTempl ...
- form表单中name和id区别
HTML文本是由HTML命令组成的描述性文本,HTML命令可以说明文字.图形.动画.声音.表格.链接等.HTML的结构包括头部(Head).主体(Body)两大部分,其中头部描述浏览器所需的信息,而主 ...