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)、写一个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 testCreate(){
/**
* 1.启动Spring容器
* 2.取出对象
* 3.调用方法
*/
ApplicationContext context=
new ClassPathXmlApplicationContext("applicationContext.xml" );
HelloWorld1 helloWorld=(HelloWorld1) context.getBean(
"helloWorld"
);
helloWorld.hello();
}
/**
*测试别名
*/
@Test
public
void testAlias(){
ApplicationContext context=
new ClassPathXmlApplicationContext("applicationContext.xml" );
HelloWorld1 helloWorld1=(HelloWorld1 ) context.getBean(
"俊哥好帅" );
helloWorld1.hello();
}
|
二、创建对象的三种方法:
1.构造函数实例化
上面的例子就是采用默认构造函数实例化的。
2.静态工厂实例化
为了控制创建对象时调用具体的某个构造函数,可以使用静态工厂来创建对象。
(1)创建静态工厂
public
class HelloFactory {
public
static HelloWorld2 getInstance(){
//使用工厂可以控制调用哪一个构造方法
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 testCreate_Factory(){
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声明在方法中。
如果把一个list集合声明在该bean的属性中,这样list成了共享的数据,所以一般情况下把list声明在方法中。
即单例的类中的属性是共享的。
2、把spring创建的bean改成prototype模式(多例模式),只需要在<bean>中写一个属性:
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中有大量的数据,需要的是用到的情况下加载
如果一个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;
说明:
如果spring中的bean是多例的情况下,spring容器不负责对象的销毁,由程序员把该对象设置为null
如果spring中的bean是多例,这个时候,不管在配置文件中lazy-init设置成什么样的值,在context.getBean时才要创建对象,而且不负责销毁
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 |