Spring(二)IOC

(1)IOC概念
Inversion of Control 控制反转。控制反转:控制权的转,即把创建对象的权利,反转给第三方spring框架去创建(new)
(2)IOC简单演示
1、创建hello类

package com.suning.Spring.IOC;

public class hello {
	public hello(){
		System.out.println("hello_create");
	}
	
	public void sayHello() {
	        System.out.println("hello spring");
	}
	
	public void init() {
	        System.out.println("Hello.init...");
	}
	
	public void destroy() {
	        System.out.println("Hello.destroy...");
	}
}

helloTest

package com.suning.Spring.IOC;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;

public class helloTest {
	
	@Test
	public void test1(){
		ApplicationContext hello = new ClassPathXmlApplicationContext("applicationContext.xml");
		hello he = hello.getBean("hello", hello.class);
		he.sayHello();
	}
}

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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	<!-- 
        <bean spring框架读取到bean的时候,就知道需要创建一个对象
        id: 创建完的对象名称,此名称必须唯一
        class: 全路径类名(包名+类名),指定spring要实例化哪一个类的对象
        底层:Object obj = 
                Class.forName("com.hdu.ioc.Hello").newInstance();
        对象实例化完毕后把id的值作为key,把实例化完的对象作为value
        存储到map集合中,以便需要时根据key来去除value
        全路径类名是否正确:ctrl+鼠标
     -->
     <bean id="hello" class="com.suning.Spring.IOC.hello"></bean>
	
</beans>

2、Spring原理:
  ①启动spring容器,并读取和解析清单文件
  ②把spring.xml中的bean节点的内容解析出并存储(map)
  ③ 循环遍历map集合中的所有数据,取出class属性对应的值,反射实例化对象
    Objectobj=Class.forName(“包名.类名”).newInstance();
  ④把所有创建完的对象存储另一个map集合,id当key,对象当value
3、getBean几种方式
//根据id,从spring容器中获取对象
//Hello hello = (Hello)context.getBean(“hello”);
//根据类型,从spring容器找那个获取对象,类型的对象必须唯一
//Hello hello = context.getBean(Hello.class);
//根据id和类型来取对象
Hello hello = context.getBean(“hello”, Hello.class);
(3)spring容器实例化对象的四种方式
1、通过无参构造的方式实例化对象(类中必须存在无参构造)

public class Hello {
    public Hello() {
        System.out.println("Hello.created");
    }
    public void sayHello() {
        System.out.println("hello spring");
    }
}

<!-- 默认构造
-->
<bean id="hello" 
          class="com.hdu.ioc.Hello">
</bean>

@Test
    public void testMethod() {
        //启动spring的容器,spring读取spring.xml文件
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"resources/spring_factory.xml"});
        //从spring容器中取出spring创建完的对象
        //根据id和类型来取对象
        Hello hello = context.getBean("hello", Hello.class);
        hello.sayHello();
    }

2、静态工厂
有些类不能直接实例化,就不能直接通过new关键字来创建,类似这样的对象我们要通过静态工厂模式来创建对象。没有静态方法就无法直接调用。

<!-- 
    静态工厂  因为getInstance这个方法是静态方法,Calendar是抽象类,不能无参构造
-->
<bean id="cal" 
      class="java.util.Calendar" 
      factory-method="getInstance" >
</bean>

public class TestIOC {
    @Test
    public void testMethod1() {
        Calendar cal = Calendar.getInstance();
        System.out.println(cal.getTime());
        
    }

3、实例工厂
静态工厂设计模式不会创建类对象,直接调用静态方法。而工厂方法设计模式会创建类,然后通过xml中配置去访问其方法。

<!-- 实例工厂  可以由程序员自己控制调用指定的方法获取对象
              但对象还不是spring创建,在别的渠道创建完交给spring容器管理
-->
<bean id="if" class="com.hdu.factory.InstanceFactory"></bean>
<bean id = "cal1"
      factory-bean="if"
      factory-method="getCalendar" >
</bean>

public class InstanceFactory {
    public Calendar getCalendar() {
        return Calendar.getInstance();
    }

public class TestIOC {
    @Test
    public void testMethod2() {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"resources/spring_factory.xml"});
        Calendar cal = context.getBean("cal1",Calendar.class);
        System.out.println(cal.getTime());
    }

4、Spring工厂
这是spring框架自身提供的,它需要实现FactoryBean接口,实现代码就必须写在getObject()方法中。spring工厂的优点在于,只要实现一个接口即可,简单方便。

<!-- spring工厂 -->
<bean id="hello" class="com.hdu.factory.SpringFactory"></bean>

public class SpringFactory implements FactoryBean<Hello>{

    @Override
    public Hello getObject() throws Exception {
        return new Hello();
    }

    @Override
    public Class<?> getObjectType() {
        return Hello.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }

public class TestIOC {
    @Test
    public void testMethod3() {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"resources/spring_factory.xml"});
        Hello hello = context.getBean("hello",Hello.class);
        hello.sayHello();
    }

(4)Spring对象
1、单例
当 scope=“singleton” 时,结果为 true。不写scope属性时,结果仍为true,证明默认对象是以单例创建的。

<!-- 
    scope:范围,如果bean节点中使用的scope属性,就是要指定当前对象的范围
    scope="singleton" 单例,默认,不写也是单例
    scope="prototype" 多例,什么时候用,什么时候实例化对象
-->
<bean id="hello" 
      class="com.hdu.ioc.Hello" 
      scope="singleton">
</bean>

public class TestIOC {
    /**
     * 测试单例和多例
     */
    @Test
    public void testMethod() {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"resources/spring.xml"});
        Hello hello = context.getBean("hello",Hello.class);
        Hello hello2 = context.getBean("hello",Hello.class);
        System.out.println(hello == hello2);
    }

2、多例
当 scope=“prototype” 时,以上测试,结果为false。

<!-- 
    scope:范围,如果bean节点中使用的scope属性,就是要指定当前对象的范围
    scope="singleton" 单例,默认,不写也是单例
    scope="prototype" 多例,什么时候用,什么时候实例化对象
-->
<bean id="hello" 
      class="com.hdu.ioc.Hello" 
      scope="prototype">
</bean>

3、懒加载
多例对象都是懒加载

<!-- 
    lazy-init="true" ,什么时候用,什么时候实例化
 -->
<bean id="hello" 
      class="com.hdu.ioc.Hello" 
      scope="singleton"
      lazy-init="true">
</bean>

在这里插入图片描述
(5)初始化和销毁方法
Hello

public class Hello {
    public Hello() {
        System.out.println("Hello.created");
    }
    public void sayHello() {
        System.out.println("hello spring");
    }
    public void init() {
        System.out.println("Hello.init...");
    }
    public void destroy() {
        System.out.println("Hello.destroy...");
    }

applicationContext

<bean id="hello" 
      class="com.hdu.ioc.Hello" 
      scope="singleton"
      init-method="init"
      destroy-method="destroy"
      lazy-init="true">
</bean>

TestIOC

public class TestIOC {
    @Test
    public void testMethod() {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"resources/spring.xml"});
        Hello hello = context.getBean("hello",Hello.class);
        ((AbstractApplicationContext) context).close();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值