本质上说,BeanFactory和ApplicationContext维护Bean定义及其相互依赖关系的高级工厂借口。通过他们我们可以访问Bean定义。
Spring的BeanFactory容器
这是一个简单的容器,它主要的功能是为依赖注入(DI)提供支持,这个容器接口在org.springframework.beans.factory.BeanFactory中被定义,在Spring中,有大量对BeanFactory接口的实现。其中,最常被使用的是XmlBeanFactory类。 这个容器从一个XML文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。
在资源宝贵的移动设备或者基于applet的应用当中,BeanFactory会被优先选择。否则,一般使用的是ApplicationContext,除非你有更好的理由选择BeanFactory。
Spring的ApplicationContext容器
Application Context是Spring中较高级的容器。和BeanFactory类似,它可以加载配置文件中定义的bean,将所有的bean集中在一起,当有请求的时候分配bean。
ApplicationContext包含BeanFactory所有的功能,一般情况下,相对于BeanFactory,ApplicationContext会被推荐使用。但BeanFactory仍然可以在轻量级应用中使用。
最常被使用的ApplicationContext接口实现:
· FileSystemXmlApplicationContext:该容器从XML文件中加载已被定义的bean。在这里,你需要提供给构造器XML文件的完整路径
· ClassPathXmlApplicationContext:该容器从XML文件中加载已被定义的bean。在这里,你不需要提供XML文件的完整路径,只需正确配置CLASSPATH环境变量即可,因为,容器会从CLASSPATH中搜索配置文件。
· WebXmlApplicationContext:该容器会在一个web应用程序的范围内加载在XML文件中已被定义的bean。
Spring中Bean的配置
Bean定义
被称作bean的对象是构成应用程序的支柱也是由SpringIoC容器管理的。bean是一个被实例化,组装,并通过SpringIoC容器所管理的对象。这些bean是由用容器提供的配置元数据创建的。
SpringIoC容器完全由实际编写的配置元数据的格式解耦。有下面三个重要的方法把配置元数据提供给Spring容器:
· 基于XML的配置文件
· 基于注解的配置
· 基于Java的配置
Bean的作用域 --------------------------------------------------------------------------
singleton 该作用域将bean的定义限制在每一个Spring IoC容器中的一个单一实例(默认)。
prototype 该作用域将单一bean的定义限制在任意数量的对象实例。
request 该作用域将bean的定义限制为HTTP请求。只在web-aware、Spring ApplicationContext的上 下文中有效。
session 该作用域将bean的定义限制为HTTP会话。
global-session 该作用域将bean的定义限制为全局HTTP会话。
bean的生命周期 --------------------------------------------------------------------------
理解Spring Bean的生命周期很容易。当一个bean被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当bean不再需要,并且从容器中移除时,可能需要做一些清除工作。
为了定义安装和拆卸一个bean,我们只要声明带有init-method和destroy-method参数的。
①初始化回调
在基于XML的配置元数据的情况下,可以使用init-method属性来指定初始化方法。
②销毁回调
在基于XML的配置元数据的情况下,可以使用destroy-method属性来制定销毁方法。
需要注意的问题:
destroy-method 只对 scope="singleton" 有效
销毁方法,必须关闭ApplicationContext对象(手动调用),才会被调用
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
applicationContext.close();
③在顶级的bean里面即元素中声明default-init-method属性,可以为容器中所有的bean指定同一个初始化或销毁回调方法。
④bean的延迟实例化
在ApplicationContext实现的默认行为就是在启动的时候将所有singleton提前进行实例化,如果不想在ApplicationContext初始化时被提前实例化,可以使用元素的"lazy-init=true"属性,一个延迟实例化的bean将在第一次被用到的时候初始化。
如果要为容器中所有的bean指定延迟实例化特性,可以在里面指定"default-lazy-init=true"属性。
指定bean的依赖关系 --------------------------------------------------------------------------
初始化beanOne会首先初始化manager1,manager2,当一个bean对多个bean存在依赖关系时,depend-on属性可以指定多个bean名,用逗号隔开。
<bean id="beanOne" depend-on="manager1,manager2"></bean> <bean id="manager1"></bean> <bean id="manager2"></bean>
Spring配置bean实例化有哪些方式?
①使用类构造器实例化(默认无参数)
id或name属性:用于指定bean的名称,用于从Spring容器中查找这个bean对象。
class属性:用于指定bean类型,会自动调用构造器创建对象。
②使用静态工厂方法实例化(简单工厂模式)
public class Person { //创建工厂类 private Person(String s){ System.out.println(s); } public void say() { System.out.println("00000000000000"); } public static Person getPerson(){ //创建静态方法 return new Person("hello"); //返回实例化的类的对象 } } public class Test { public static void main(String[] args) { ApplicationContext ctx =new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = (Person) ctx.getBean("person"); person.say(); } }
<bean id="speaker03" class="com.mahaochen.spring.learn03.Speaker" factory-method="getPerson"> </bean>
③使用实例工厂方法实例化
实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法。
public class People { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
<bean id="PeopleFactory" class="com.mahaochen.spring.PeopleFactory"></bean> <!-- 使用实例工厂Bean创建Bean --> <bean id="" class="com.mahaochen.spring.Speaker" factory-bean="PeopleFactory" factory-method="createPeopleInstance" > </bean>