IoC :inverse of control 控制反转:把对象的创建、初始化、销毁等工作交给spring容器来做,由spring容器控制对象的生命周期。
一.创建对象及别名
对象的创建的过程:
(1)、写一个java类
(2)、写一个spring的配置文件,把该类放入到spring容器中
<bean id="helloWorld" class="com.xxx.HelloWorld"></bean>
(3)、启动spring容器
(4)、把对象从spring容器中取出来
(5)、对象调用方法
说明:bean中的id值是唯一的,不能出现相同的ID值
1.导包:
spring.jar;
commons-logging.jar;
2.创建一个HelloWorld类,提供hello方法;
3.src根目录下新建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-2.5.xsd"> <!-- 把一个类放入到spring容器中,该类为bean --> <!-- id 唯一标识 把helloWorld放入到spring容器中了 --> <bean id="helloWorld" class="com.oterman.create.HelloWorld1" ></bean> <!-- 给helloWorld创建一个别名,注意name属性的值和bean的ID的值一致 <alias name="helloWorld" alias= "俊哥好帅" /> </beans> |
4.测试获取对象
/** * 测试创建对象 */ @Test public void /** * 1.启动Spring容器 * 2.取出对象 * 3.调用方法 */ ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml" ); HelloWorld1 helloWorld=(HelloWorld1) context.getBean("helloWorld" ); helloWorld.hello(); } /** *测试别名 */ @Test public void ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml" ); HelloWorld1 helloWorld1=(HelloWorld1 ) helloWorld1.hello(); } |
二、创建对象的三种方法:
1.构造函数实例化
上面的例子就是采用默认构造函数实例化的。
2.静态工厂实例化
为了控制创建对象时调用具体的某个构造函数,可以使用静态工厂来创建对象。
(1)创建静态工厂
public class HelloFactory { public static HelloWorld2 //使用工厂可以控制调用哪一个构造方法 return new HelloWorld2(); } } |
(2)在applicationContext_createMethod.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-2.5.xsd"> <bean id="helloWorld2" class="com.oterman.createmethod.HelloWorld2" ></bean > <bean id="helloFactory" class="com.oterman.createmethod.HelloFactory" factory-method="getInstance" ></bean> </beans> |
(3)在applicationContext.xml中引入上述xml文件:
< import resource ="com/oterman/createmethod/applicationContext_createMethod.xml" ></import> |
(4)测试:
/** * 采用静态工厂模式创建对象 */ @Test public void ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml" ); HelloWorld2 helloWorld2=(HelloWorld2) context.getBean("helloFactory" ); helloWorld2.hello(); } |
3.实例工厂实例化(略)
三. spring的scope
scope表示创建的对象是单例还是多例。
1、spring创建对象默认是单例模式scope="singleton":
如果把一个list集合声明在该bean的属性中,这样list成了共享的数据,所以一般情况下把list声明在方法中。
即单例的类中的属性是共享的。
2、把spring创建的bean改成prototype模式(多例模式),只需要在<bean>中写一个属性:
scope ="prototype"
四.spring什么时候创建对象
1. scope="singleton",单例模式:
(1)、在默认情况下(lazy-init=false或default),spring容器启动的时候,就创建对象了;
优点:有利于开发,当spring容器启动的时候,如果配置文件中有错误,则会报错
(2)、lazy-init="true",即开启延迟初始化,当从spring容器中获取bean的时候创建对象;
如果所有的bean按照这种模式加载,当spring容器启动的时候是不会报错的
如果一个bean中有大量的数据,需要的是用到的情况下加载
2.scope="prototype",多例模式:
如果spring中的bean是多例,这个时候,不管在配置文件中lazy-init设置成什么样的值,
在context.getBean时才要创建对象,而且不负责销毁 .
即设置了scope="prototype"后,不用再设置lazy-init了,设置了也没有用。
五.spring容器的初始化和销毁:
前提条件:spring中的bean是单例的,scope="singleton":
1、在一个bean中可以提供init方法和destroy方法:
<bean>标签中可以设置:
init-method:初始化方法
destroy-method:销毁方法
2、当创建对象完成以后,直接执行init方法,该方法由spring容器来执行:
①lazy-init="false":
spring容器启动->构造方法->init()方法;
②lazy-init="true":
spring启动->context.getBean()->构造方法->init()方法;
3、当spring容器关闭的时候,执行destroy方法,该方法由spring容器来执行,由该方法释放资源
ClassPathXmlApplicationContext xmlApplicationContext = (ClassPathXmlApplicationContext)context;
xmlApplicationContext.close();
说明:
如果spring中的bean是多例的情况下,spring容器不负责对象的销毁,由程序员把该对象设置为null
如果spring中的bean是多例,这个时候,不管在配置文件中lazy-init设置成什么样的值,在context.getBean时才要创建对象,而且不负责销毁
六.解决spring配置文件没提示问题:
windows-->preference--->myeclipse--->files and editors-->xml--->xmlcatalog 点击add ,在出现的窗口中的 Key Type 中选择URI,在location中选择File system,然后找到spring-beans-2.5.xsd文件所在地, 应该把窗口中的 Key Type改为Schema location , Key 改为http://www.springframework.org/schema/beans/spring-beans-2.5.xsd |
版权声明:本文为博主原创文章,未经博主允许不得转载。