Spring 容器是 Spring 框架的核心。容器建立对象,把它们链接在一块儿,配置它们,并管理他们的整个生命周期,从建立到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans。java
配置bean能够经过 XML,也能够经过Java 注释或 Java 代码来实现。web
下图是 Spring 如何工做的高级视图。 Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成彻底配置和可执行的系统或应用程序。spring
这是一个最简单的容器,它主要的功能是为依赖注入 (DI) 提供支持,这个容器接口在 org.springframework.beans.factory.BeanFactor 中被定义。session
在 Spring 中,有大量对 BeanFactory 接口的实现。其中,最常被使用的是 XmlBeanFactory 类。这个容器从一个 XML 文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。app
在资源宝贵的移动设备或者基于 applet 的应用当中, BeanFactory 会被优先选择。不然,通常使用的是 ApplicationContext,除非你有更好的理由选择 BeanFactory。框架
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml")); HelloWorld obj = (HelloWorld) factory.getBean("helloWorld"); obj.getMessage();
Application Context 是 spring 中较高级的容器。和 BeanFactory 相似,它能够加载配置文件中定义的 bean。 另外,它增长了企业所须要的功能,好比,从属性文件中解析文本信息和将事件传递给所指定的监听器。ApplicationContext 包含 BeanFactory 全部的功能,通常状况下,相对于 BeanFactory,ApplicationContext 会更加优秀。固然,BeanFactory 仍能够在轻量级应用中使用,好比移动设备或者基于 applet 的应用程序。post
最常被使用的 ApplicationContext 接口实现:测试
ApplicationContext context = new FileSystemXmlApplicationContext ("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage();
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage();
被称做 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。spa
Bean的常见属性code
Id/_Name(不可重复) | 这个属性指定惟一的 bean 标识符。在基于 XML 的配置元数据中,你可使用 ID 和/或 name 属性来指定 bean 标识符 |
Class | 这个属性是强制性的,而且指定用来建立 那个类的 bean 类 |
Scope | 这个属性指定由特定的 bean 定义建立的对象的做用域(默认Singleton) |
Constructor-arg | 使用构造方法注入依赖关系的 |
Properties | 使用setter方法注入依赖 |
Autuwire | 自动匹配并注入依赖(默认为no,不自动匹配) |
Lazy-init | 告诉容器延迟初始化bean,制动请求才建立(默认值false,容器建立自动建立对象) |
Init-method | 在实例化 bean 时,当即调用该方法 |
Destroy-method | 从容器中移除 bean 以后,调用该方法 |
Bean的做用域scope属性(默认值singleton)
Singleton | ioc容器中只存在一个bean实例,bean以单例存在 |
Prototype | 每次从容器请求bean是,都会建立一个新的bean对象 |
Request | 每次http请求都会建立一个新的bean对象 |
Session | 同一个http session共享一个bean |
global-session | 通常用于Portlet应用环境 |
当一个 bean 被实例化时,它可能须要执行一些初始化使它转换成可用状态。一样,当 bean 再也不须要,而且从容器中移除时,可能须要作一些清除工做。init-method 属性指定一个方法,在实例化 bean 时,当即调用该方法。一样,destroy-method 指定一个方法,只有从容器中移除 bean 以后,才能调用该方法。
只要声明带有 init-method 和/或 destroy-method 参数的 :
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld" init-method="init" destroy-method="destroy"> <property name="message" value="Hello World!"/> </bean>
若是想要测试调用destroy-method方法,须要调用在 AbstractApplicationContext 类中声明的关闭 hook 的 registerShutdownHook() 方法。它将确保正常关闭,而且调用相关的 destroy 方法。
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); context.registerShutdownHook();
尽管还有一些在 Bean 实例化和销毁之间发生的活动,可是本章将只讨论两个重要的生命周期回调方法,它们在 bean 的初始化和销毁的时候是必需的。
实现两个接口,并重写方法,代替了xml中配置init-method和destroy-method元素
初始化回调
public class ExampleBean implements InitializingBean { public void afterPropertiesSet() { // do some initialization work } }
public class ExampleBean implements DisposableBean { public void destroy() { // do some destruction work } }
建议你不要使用 InitializingBean 或者 DisposableBean 的回调方法,由于 XML 配置在命名方法上提供了极大的灵活性。
若是你有太多具备相同名称的初始化或者销毁方法的 Bean,那么你不须要在每个 bean 上声明初始化方法和销毁方法。框架使用 元素中的 default-init-method 和 default-destroy-method 属性提供了灵活地配置这种状况
BeanPostProcessor接口定义回调方法,你能够实现该方法来提供本身的实例化逻辑,依赖解析逻辑等。
任何bean的初始化的以前和以后输入该bean的名称。在初始化bean的以前和以后实现更复杂的逻辑
public class InitHelloWorld implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeforeInitialization : " + beanName); return bean; // you can return any other object as well } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("AfterInitialization : " + beanName); return bean; // you can return any other object as well } }
注册接口的实现类
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld" init-method="init" destroy-method="destroy"> <property name="message" value="Hello World!"/> </bean> <!-- 注册接口的实现类--> <bean class="com.tutorialspoint.InitHelloWorld" />
子 bean 的定义继承父定义的配置数据。子定义能够根据须要重写一些值,或者添加其余值。
你能够建立一个 Bean 定义模板,不须要花太多功夫它就能够被其余子 bean 定义使用。在定义一个 Bean 定义模板时,不指定类的属性,而应该指定带 true 值的抽象属性,以下所示:
<bean id="beanTeamplate" abstract="true"> <property name="message1" value="Hello World!"/> <property name="message2" value="Hello Second World!"/> <property name="message3" value="Namaste India!"/> </bean> <bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="beanTeamplate"> <property name="message1" value="Hello India!"/> <property name="message3" value="Namaste India!"/> </bean>
父 bean 自身不能被实例化,由于它是不完整的,并且它也被明确地标记为抽象的。当一个定义是抽象的,它仅仅做为一个纯粹的模板 bean 定义来使用的,充当子定义的父定义使用。