1,简介:

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

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

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

  1,默认无参构造器创建

  2,静态工厂方法创建

  3,实例工厂方法创建

无参构造器创建:

applicationContext.cml配置:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.  
  6. <!--无参构造器-->
  7. <bean id="bean1" class="com.zy.IoC.Bean1"></bean>
  8. </beans>

JavaBean类 Bean1:

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

测试:

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

运行结果:

静态工厂方法创建:

applicationContext.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.  
  6. <!--无参构造器-->
  7. <bean id="bean1" class="com.zy.IoC.Bean1"></bean>
  8. <!--静态工厂方法-->
  9. <bean id="bean2" class="com.zy.IoC.Bean2Factory" factory-method="getBean2"></bean>
  10. </beans>

JavaBean类 Bean2:

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

静态工厂:

  1. public class Bean2Factory {
  2. public Bean2Factory() {
  3. System.out.println("Bean2Factory 的构造方法");
  4. }
  5.  
  6. public static Bean2 getBean2(){
  7. return new Bean2();
  8. }
  9. }

测试:

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

运行结果:

实例工厂方法创建:

applicationContext.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.  
  6. <!--无参构造器-->
  7. <bean id="bean1" class="com.zy.IoC.Bean1"></bean>
  8. <!--静态工厂方法-->
  9. <bean id="bean2" class="com.zy.IoC.Bean2Factory" factory-method="getBean2"></bean>
  10. <!--实例化工厂方法-->
  11. <bean id="bean3Factory" class="com.zy.IoC.Bean3Factory"></bean>
  12. <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
  13. </beans>

JavaBean类 Bean3:

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

工厂:

  1. public class Bean3Factory {
  2. public Bean3Factory() {
  3. System.out.println("Bean3Factory 的构造方法");
  4. }
  5.  
  6. public Bean3 getBean3(){
  7. return new Bean3();
  8. }
  9. }

测试:

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

运行结果:

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

实现FactoryBean接口:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.  
  6. <!--配置bean标签,提供对象实现类型-->
  7. <!--id或者name 是对象的唯一标识 class配置对象的全路径-->
  8. <bean id="userDao" class="com.zy.dao.impl.UserDaoImpl2"></bean>
  9. <bean id="userService" lazy-init="true" class="com.zy.service.impl.UserServiceImpl">
  10. <property name="userDao" ref="userDao"></property>
  11. </bean>
  12.  
  13. <!--无参构造器-->
  14. <bean id="bean1" class="com.zy.IoC.Bean1" lazy-init="true"></bean>
  15. <!--静态工厂方法-->
  16. <bean id="bean2" class="com.zy.IoC.Bean2Factory" factory-method="getBean2"></bean>
  17. <!--实例化工厂方法-->
  18. <bean id="bean3Factory" class="com.zy.IoC.Bean3Factory"></bean>
  19. <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
  20.  
  21. <!--自己创建工厂(实现FactoryBean接口)-->
  22. <bean id="bean3_2" class="com.zy.IoC.MyFactoryBean"></bean>
  23. </beans>

自己创建的工厂:

  1. public class MyFactoryBean implements FactoryBean {
  2. @Override
  3. public Object getObject() throws Exception {
  4. //这里返回实例
  5. return new Bean3();
  6. }
  7.  
  8. @Override
  9. public Class<?> getObjectType() {
  10. return null;
  11. }
  12.  
  13. @Override
  14. public boolean isSingleton() {
  15. return false;
  16. }
  17. }

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

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

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

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

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

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.  
  6. <!--无参构造器-->
  7. <bean id="bean1" class="com.zy.IoC.Bean1" lazy-init="true"></bean>
  8. <!--静态工厂方法-->
  9. <bean id="bean2" class="com.zy.IoC.Bean2Factory" factory-method="getBean2"></bean>
  10. <!--实例化工厂方法-->
  11. <bean id="bean3Factory" class="com.zy.IoC.Bean3Factory"></bean>
  12. <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
  13. </beans>

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

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

Scope:(Bean的作用域配置)

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

重点为singleton和prototype:

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

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

实例如下:

  1. // 单例
  2. public class SingletonBean {
  3. public SingletonBean() {
  4. System.out.println("单实例Bean SingletonBean 初始化...");
  5. }
  6. }
  7. // 多实例
  8. public class PrototypeBean {
  9. public PrototypeBean() {
  10. System.out.println("多实例bean PrototypeBean 初始化 ...");
  11. }
  12. }

配置:

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

测试:

  1. @Test
  2. public void testScope() {
  3. ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
  4. "applicationContext.xml");
  5. // 单例
  6. SingletonBean singletonBean1 = (SingletonBean) applicationContext
  7. .getBean("singletonBean");
  8. SingletonBean singletonBean2 = (SingletonBean) applicationContext
  9. .getBean("singletonBean");
  10. System.out.println(singletonBean1);
  11. System.out.println(singletonBean2);
  12.  
  13. // 多例
  14. PrototypeBean prototypeBean1 = (PrototypeBean) applicationContext
  15. .getBean("prototypeBean");
  16. PrototypeBean prototypeBean2 = (PrototypeBean) applicationContext
  17. .getBean("prototypeBean");
  18. System.out.println(prototypeBean1);
  19. System.out.println(prototypeBean2);
  20. }

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

4,Spring容器的生命周期

JavaBean类:

  1. public class SpringLifeCycle {
  2. //构造方法
  3. public SpringLifeCycle() {
  4. System.out.println("SpringLifeCycle 构造...");
  5. }
  6. //初始化方法
  7. public void init() {
  8. System.out.println("SpringLifeCycle 初始化...");
  9. }
  10. //销毁方法
  11. public void destroy() {
  12. System.out.println("SpringLifeCycle 销毁...");
  13. }
  14.  
  15. public void helloSpring() {
  16. System.out.println("hello spring !");
  17. }
  18. }

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

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

测试:

  1. @Test
  2. public void testScope() {
  3. ApplicationContext ac = new ClassPathXmlApplicationContext(
  4. "applicationContext.xml");
  5. SpringLifeCycle springLifeCycle = (SpringLifeCycle) ac.getBean("springLifeCycle");
  6. springLifeCycle.helloSpring();
  7.  
  8. // 调用close(ApplicationContext没有close方法,需要转子类调用close)
  9. ClassPathXmlApplicationContext classAc = (ClassPathXmlApplicationContext) ac;
  10. classAc.close();
  11. }

运行结果:

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. Tomcat应用服务器被黑客 肉鸡攻击 记录

    线上一台应用服务器报警,负载过高,这个就诡异了,因为只是一个普通的服务器,应用使用人员不到10个人,咋会负载高,肯定有问题哪,登陆上去查看, top查看哪个占据的cpu资源比较多 [root@aew0 ...

  2. Python之属性、特性和修饰符

    作为面对对象的核心内容,将从以下一个方面进行总结: 1. property和@property 2. __getattribute__().__getattr__().__setattr__().__ ...

  3. eclipse中package explore和project explore 怎么相互切换???

    window--->show view--->other---->Java---->Package Explorer或者选project explore之后就可以相互切换了

  4. SVN客户端与服务器端搭建操作

    一.客户端的安装 1.点击安装程序 2.修改svn安装位置 3.开始安装 4.客户端安装成功 5.回到左面  右键出现svn检出 tortoiSVN  表示安装成功 Myeclipse svn插件安装 ...

  5. 【sqlite】基础知识

    最近做一个数控系统的项目,winCE嵌入式操作系统+.Net Compact Framework环境+VS2008开发平台,开发的设备程序部署到winCE系统下的设备中运行.. 个年头,SQLite也 ...

  6. Oracle Sql Developer 连接oracle

    PL/Sql 初次使用需要配置文件内容,对于我这种Oracle新手来说各种配置有点凌乱,所以果断选择Sql Developer. 选择它是因为初次使用的时候它不用想PL/Sql那样配置文件,而只需要添 ...

  7. String类的一些常规方法

    String类 String类常用方法: ①length(): length()       长度    方法** 对比:数组.length      属性** 一般情况下,一个数字,一个字母,一个汉 ...

  8. spring--Autowired setter 方法

    在Spring中,可以使用 @Autowired 注解通过setter方法,构造函数或字段自动装配Bean.此外,它可以在一个特定的bean属性自动装配. 注 @Autowired注解是通过匹配数据类 ...

  9. 系列文章--SharePoint 2013 Designer 入门教程

    SharePoint的使用中,SharePoint Designer是非常重要的工具,我们可以通过Designer设计页面.母版页,维护.管理站点,也可以定制列表表单.数据视图,设计工作流等等.下面总 ...

  10. Redis事件库源码分析

    由于老大在新项目中使用redis的事件库代替了libevent,我也趁着机会读了一遍redis的事件库代码,第一次读到“优美,让人愉快”的代码,加之用xmind制作的类图非常帅,所以留文纪念. Red ...