Spring学习笔记(二) IoC容器与Bean
2016-09-19 21:18
711 查看
本文为Spring的学习笔记,有参考极客学院的wiki内容。
(我的博客原文地址:https://chaycao.github.io/2016/09/19/StudyNotesOfSpring2/ 请多指教!)
Spring容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans。
通过阅读配置元数据提供的指令,容器知道对哪些对象进行实例化,配置和组装。
配置元数据的三种表示方式: XML,Java 注释、 Java 代码
下图是 Spring 如何工作的高级视图。 Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序。
Spring提供了两种不同类型的容器
- Spring BeanFactory 容器
最简单的容器,给DI提供了基本支持,由org.springframework.beans.factory.BeanFactory接口来定义。
- Spring ApplicationContext 容器
该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给感兴趣的事件监听器的能力。该容器是由 org.springframework.context.ApplicationContext 接口定义。
ApplicationContext 容器包括 BeanFactory 容器的所有功能,所以通常建议使用 ApplicationContext。 BeanFactory 仍然可以用于轻量级的应用程序,如移动设备或基于 applet 的应用程序,其中它的数据量和速度是显著。
以 笔记(一) 中的 HelloWorld实例 为例。
HelloWorld.java 和 Beans.xml 内容不变
下面是MainApp.java的内容:
第一步利用框架提供的 XmlBeanFactory() API 去生成工厂 bean 以及利用 ClassPathResource() API 去加载在路径 CLASSPATH 下可用的 bean 配置文件。XmlBeanFactory() API 负责创建并初始化所有的对象,即在配置文件中提到的 bean。
第二步利用第一步生成的 bean 工厂对象的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象,该对象最后可以用于实际的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。
- FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器* XML 文件的完整路径*
- ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。
- WebXmlApplicationContext:该容器会在一个* web 应用程序的范围内*加载在 XML 文件中已被定义的 bean。
在 笔记(一) 中的 HelloWorld实例 中,我们已经使用过了 ClassPathXmlApplicationContext 容器。 WebXmlApplicationContext将在后面的章节使用,这里写一个 FileSystemXmlApplicationContext 的例子:
HelloWorld.java 和 Beans.xml 的内容不变
下面是 MainApp.java 的内容:
第一步生成工厂对象。加载完指定路径下 bean 配置文件后,利用框架提供的 FileSystemXmlApplicationContext API 去生成工厂bean。FileSystemXmlApplicationContext 负责生成和初始化所有的对象,比如,所有在 XML bean 配置文件中的 bean。
第二步利用第一步生成的上下文中的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。
配置元数据具有以下信息:
- 如何创建一个 bean
- bean 的生命周期的详细信息
- bean 的依赖关系
上述所有的配置元数据转换成一组构成每个 bean 定义的下列属性。
- class : 强制的,指定用来创建 bean 的 bean 类
- name : 指定唯一的 bean 标识符。在基于 XML 的配置元数据中,可用ID或name属性指定 bean 标识符
- scope : 指定由特定的 bean 定义创建的对象的作用域
- constructor-arg : 用来注入依赖关系,后面讨论
- properties : 用来注入依赖关系,后面讨论
- autowiring mode : 用来注入依赖关系,后面讨论
- lazy-initialization mode : 延迟初始化 bean
- initialization 方法 : 在 bean 的所有必须的属性被容器设置后,调用回调方法
- destruction 方法 : 当包含该 bean 的容器被销毁时,调用回调方法
下面给出一个基于 XML 配置文件的例子,给出不同的 bean 定义:
1. singleton : 将 bean 的定义限制在每一个 Spring IoC容器中的一个单一实例(默认)
2. prototype : 将单一 bean 的定义限制在任意数量的对象实例。
3. request : 将 bean 的定义限制为 HTTP 请求。只在 web-aware Spring ApplicationContext 的上下文中有效。
4. session : 将 bean 的定义限制为 HTTP 会话。只在 web-aware Spring ApplicationContext 的上下文中有效。
5. global-session : 将 bean 的定义限制为全局 HTTP 会话。只在 web-aware Spring ApplicationContext 的上下文中有效。
本章只讨论前两个,后三个当讨论到 web-aware Spring ApplicationContext 的时候讨论。
该单一实例将存储在这种单例 bean 的高速缓存中,以及针对该 bean 的所有后续的请求和引用都返回缓存对象。
默认作用域始终是 singleton ,也可以在 bean 的配置文件中配置:
下面看一个例子,MainApp.java的内容如下
输出结果如下:
一般,有状态的 bean 使用 prototype 作用域,无状态的 bean 使用 singleton 作用域。
可以在 XML 配置文件中设置作用域为 prototype
下面给出一个例子,MainApp.java文件内容如下:
输出:
本章只讨论两个重要的生命周期回调方法,它们在bean的初始化和销毁是必须的。
org.springframework.beans.factory.InitializingBean 接口指定一个单一的方法:
通过实现上述接口,初始化工作就可以在 afterPropertiesSet() 方法中执行,如下所示:
第二种方式:在基于 XML 的配置元数据中, init-method 属性指定带有void无参数方法的名称。例如:
下面是类的定义:
org.springframework.beans.factory.DisposableBean 接口指定一个单一的方法:
通过实现上述接口,结束工作就可以在 destroy() 方法中执行,如下所示:
第二种方式:在基于 XML 的配置元数据中, destory-method 属性指定带有void无参数方法的名称。例如:
下面是类的定义:
如果在非 web 应用程序环境中使用 Spring 的 IoC 容器(例如丰富的客户端桌面环境),那么在 JVM 中要注册关闭hook,确保正常关闭,让所有资源被释放,可以在单个 bean 上调用 destory 方法。
建议:使用第二种方式,因为 XML 配置在命名方法上具有极大的灵活性。
当有多个 BeanPostProcessor 实现类时,可通过设置 BeanPostProcessor 接口实现的 Ordered 接口提供的 order 属性来控制这些 BeanPostProcessor 实现类的执行顺序。
ApplicationContext 会自动检测由 BeanPostProcessor 接口的实现定义的 bean,注册这些 bean 为后置处理器,然后通过在容器中创建 bean,在适当的时候调用它。
下面是一个例子:
这里是 HelloWorld.java 的内容:
下面 InitHelloWorld 实现了 BeanPostProcessor 接口,并且实现接口定义的两个方法 postProcessBeforeInitialization() postProcessAfterInitialization(),第一个参数为bean的Object对象,第二个参数为bean的名称。当初始化任意一个bean前,回调第一个函数。初始化任意一个bean后,回调第二个函数。
下面是 MainApp.java 的内容。注册一个在 AbstractApplicationContext 类中声明的关闭 hook 的 registerShutdownHook() 方法,确保正常关闭,并且调用相关的 destory 方法。
下面是 init 和 destory 方法需要的配置文件 Beans.xml 文件:
输出:
Spring Bean 定义的继承与 Java 类的继承无关,但是继承的概念是一样的。可以定义一个父 bean 的定义作为模板和其他子 bean 就可以从父 bean 中继承所需的配置。
例子:
下面是配置文件 Beans.xml ,“helloworld” bean 有两个属性 message1 和 message2 。然后使用 parent 属性把 “helloIndia” bean 定义为 “helloWorld” bean 的孩子,并继承它的属性,同时自己还添加一个属性 message3。
下面是 HelloWorld.java 的内容:
下面是 HelloIndia.java 的内容:
下面是 MainApp.java 的内容:
输出:
在创建 “helloIndia” bean 的同时并没有传递 message2,但由于 Bean 定义的继承,所以传递了 message2。
Bean 定义模板
在定义一个 Bean 定义模板时,不指定class的属性,将abstract的属性置为 true,如下所示:
(我的博客原文地址:https://chaycao.github.io/2016/09/19/StudyNotesOfSpring2/ 请多指教!)
IoC容器
Spring容器是Spring框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans。
通过阅读配置元数据提供的指令,容器知道对哪些对象进行实例化,配置和组装。
配置元数据的三种表示方式: XML,Java 注释、 Java 代码
下图是 Spring 如何工作的高级视图。 Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序。
Spring提供了两种不同类型的容器
- Spring BeanFactory 容器
最简单的容器,给DI提供了基本支持,由org.springframework.beans.factory.BeanFactory接口来定义。
- Spring ApplicationContext 容器
该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给感兴趣的事件监听器的能力。该容器是由 org.springframework.context.ApplicationContext 接口定义。
ApplicationContext 容器包括 BeanFactory 容器的所有功能,所以通常建议使用 ApplicationContext。 BeanFactory 仍然可以用于轻量级的应用程序,如移动设备或基于 applet 的应用程序,其中它的数据量和速度是显著。
BeanFactory 容器
在Spring中,有大量对BeanFactory接口的实现。其中,最常见的是 XmlBeanFactory 类。这个容器从一个 XML 文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。以 笔记(一) 中的 HelloWorld实例 为例。
HelloWorld.java 和 Beans.xml 内容不变
下面是MainApp.java的内容:
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; public class MainApp { public static void main(String[] args) { XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource("Beans.xml")); HelloWorld obj = (HelloWorld) factory.getBean("helloWorld"); obj.getMessage(); } }
第一步利用框架提供的 XmlBeanFactory() API 去生成工厂 bean 以及利用 ClassPathResource() API 去加载在路径 CLASSPATH 下可用的 bean 配置文件。XmlBeanFactory() API 负责创建并初始化所有的对象,即在配置文件中提到的 bean。
第二步利用第一步生成的 bean 工厂对象的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象,该对象最后可以用于实际的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。
Spring ApplicationContext容器
最常被使用的 ApplicationContext 接口实现:- FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器* XML 文件的完整路径*
- ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。
- WebXmlApplicationContext:该容器会在一个* web 应用程序的范围内*加载在 XML 文件中已被定义的 bean。
在 笔记(一) 中的 HelloWorld实例 中,我们已经使用过了 ClassPathXmlApplicationContext 容器。 WebXmlApplicationContext将在后面的章节使用,这里写一个 FileSystemXmlApplicationContext 的例子:
HelloWorld.java 和 Beans.xml 的内容不变
下面是 MainApp.java 的内容:
import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext ("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); } }
第一步生成工厂对象。加载完指定路径下 bean 配置文件后,利用框架提供的 FileSystemXmlApplicationContext API 去生成工厂bean。FileSystemXmlApplicationContext 负责生成和初始化所有的对象,比如,所有在 XML bean 配置文件中的 bean。
第二步利用第一步生成的上下文中的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。
Bean 定义
bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由用容器提供的配置元数据创建的。配置元数据具有以下信息:
- 如何创建一个 bean
- bean 的生命周期的详细信息
- bean 的依赖关系
上述所有的配置元数据转换成一组构成每个 bean 定义的下列属性。
- class : 强制的,指定用来创建 bean 的 bean 类
- name : 指定唯一的 bean 标识符。在基于 XML 的配置元数据中,可用ID或name属性指定 bean 标识符
- scope : 指定由特定的 bean 定义创建的对象的作用域
- constructor-arg : 用来注入依赖关系,后面讨论
- properties : 用来注入依赖关系,后面讨论
- autowiring mode : 用来注入依赖关系,后面讨论
- lazy-initialization mode : 延迟初始化 bean
- initialization 方法 : 在 bean 的所有必须的属性被容器设置后,调用回调方法
- destruction 方法 : 当包含该 bean 的容器被销毁时,调用回调方法
下面给出一个基于 XML 配置文件的例子,给出不同的 bean 定义:
<?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.xsd"> <!-- A simple bean definition --> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- A bean definition with lazy init set on --> <bean id="..." class="..." lazy-init="true"> <!-- collaborators and configuration for this bean go here --> </bean> <!-- A bean definition with initialization method --> <bean id="..." class="..." init-method="..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- A bean definition with destruction method --> <bean id="..." class="..." destroy-method="..."> <!-- collaborators and configuration for this bean go here --> </bean> </beans>
Bean 作用域
Spring 框架支持以下五个作用域 :1. singleton : 将 bean 的定义限制在每一个 Spring IoC容器中的一个单一实例(默认)
2. prototype : 将单一 bean 的定义限制在任意数量的对象实例。
3. request : 将 bean 的定义限制为 HTTP 请求。只在 web-aware Spring ApplicationContext 的上下文中有效。
4. session : 将 bean 的定义限制为 HTTP 会话。只在 web-aware Spring ApplicationContext 的上下文中有效。
5. global-session : 将 bean 的定义限制为全局 HTTP 会话。只在 web-aware Spring ApplicationContext 的上下文中有效。
本章只讨论前两个,后三个当讨论到 web-aware Spring ApplicationContext 的时候讨论。
singleton 作用域
如果作用域为 singleton,那么 Spring IoC容器中只能创建一个由该 bean 定义的对象的实例。该单一实例将存储在这种单例 bean 的高速缓存中,以及针对该 bean 的所有后续的请求和引用都返回缓存对象。
默认作用域始终是 singleton ,也可以在 bean 的配置文件中配置:
<!-- A bean definition with singleton scope --> <bean id="..." class="..." scope="singleton"> <!-- collaborators and configuration for this bean go here --> </bean>
下面看一个例子,MainApp.java的内容如下
public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.setMessage("I'm object A"); objA.getMessage(); HelloWorld objB = (HelloWorld) context.getBean("helloWorld"); objB.getMessage(); } }
输出结果如下:
Your Message : I'm object A Your Message : I'm object A
prototype 作用域
如果作用域设置为 prototype,那么每次特定的 bean 发出请求时 Spring IoC 容器就创建对象的新的 Bean 实例。一般,有状态的 bean 使用 prototype 作用域,无状态的 bean 使用 singleton 作用域。
可以在 XML 配置文件中设置作用域为 prototype
<!-- A bean definition with singleton scope --> <bean id="..." class="..." scope="prototype"> <!-- collaborators and configuration for this bean go here --> </bean>
下面给出一个例子,MainApp.java文件内容如下:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.setMessage("I'm object A"); objA.getMessage(); HelloWorld objB = (HelloWorld) context.getBean("helloWorld"); objB.getMessage(); } }
输出:
Your Message : I'm object A Your Message : null
Bean 生命周期
当一个bean被实例化时,可能需要执行一些初始化使它转换成可用状态。当bean不再需要,并且从容器中移除时,可能做一些清楚工作。本章只讨论两个重要的生命周期回调方法,它们在bean的初始化和销毁是必须的。
初始化回调
第一种方式:实现相应的接口org.springframework.beans.factory.InitializingBean 接口指定一个单一的方法:
void afterPropertiesSet() throws Exception;
通过实现上述接口,初始化工作就可以在 afterPropertiesSet() 方法中执行,如下所示:
public class ExampleBean implements InitializingBean { public void afterPropertiesSet() { // do some initialization work } }
第二种方式:在基于 XML 的配置元数据中, init-method 属性指定带有void无参数方法的名称。例如:
<bean id="exampleBean" class="examples.ExampleBean" init-method="init"/>
下面是类的定义:
public class ExampleBean { public void init() { // do some initialization work } }
销毁回调
第一种方式:实现相应的接口org.springframework.beans.factory.DisposableBean 接口指定一个单一的方法:
void destroy() throws Exception;
通过实现上述接口,结束工作就可以在 destroy() 方法中执行,如下所示:
public class ExampleBean implements DisposableBean { public void destroy() { // do some destruction work } }
第二种方式:在基于 XML 的配置元数据中, destory-method 属性指定带有void无参数方法的名称。例如:
<bean id="exampleBean" class="examples.ExampleBean" destroy-method="destroy"/>
下面是类的定义:
public class ExampleBean { public void destroy() { // do some destruction work } }
如果在非 web 应用程序环境中使用 Spring 的 IoC 容器(例如丰富的客户端桌面环境),那么在 JVM 中要注册关闭hook,确保正常关闭,让所有资源被释放,可以在单个 bean 上调用 destory 方法。
建议:使用第二种方式,因为 XML 配置在命名方法上具有极大的灵活性。
默认的初始化和销毁方法
如果有太多具有相同名称的初始化或者销毁方法的 Bean,那么不需要在 bean 上声明初始化方法和销毁方法。框架使用元素中 default-init-method 和 default-destory-method 属性提供了灵活地配置这种情况,如下所示:<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.xsd" default-init-method="init" default-destroy-method="destroy"> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> </beans>
Bean 后置处理器
BeanPostProcessor 接口定义回调方法,你可以在 Spring 容器通过插入一个或多个 BeanPostProcessor 的实现来完成实例化,配置和初始化一个bean之后实现一些自定义逻辑回调方法。当有多个 BeanPostProcessor 实现类时,可通过设置 BeanPostProcessor 接口实现的 Ordered 接口提供的 order 属性来控制这些 BeanPostProcessor 实现类的执行顺序。
ApplicationContext 会自动检测由 BeanPostProcessor 接口的实现定义的 bean,注册这些 bean 为后置处理器,然后通过在容器中创建 bean,在适当的时候调用它。
下面是一个例子:
这里是 HelloWorld.java 的内容:
public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage(){ System.out.println("Your Message : " + message); } public void init(){ System.out.println("Bean is going through init."); } public void destroy(){ System.out.println("Bean will destroy now."); } }
下面 InitHelloWorld 实现了 BeanPostProcessor 接口,并且实现接口定义的两个方法 postProcessBeforeInitialization() postProcessAfterInitialization(),第一个参数为bean的Object对象,第二个参数为bean的名称。当初始化任意一个bean前,回调第一个函数。初始化任意一个bean后,回调第二个函数。
import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.BeansException; 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 } }
下面是 MainApp.java 的内容。注册一个在 AbstractApplicationContext 类中声明的关闭 hook 的 registerShutdownHook() 方法,确保正常关闭,并且调用相关的 destory 方法。
import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); context.registerShutdownHook(); } }
下面是 init 和 destory 方法需要的配置文件 Beans.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.xsd"> <bean id="helloWorld" class="com.chaycao.HelloWorld" init-method="init" destroy-method="destroy"> <property name="message" value="Hello World!"/> </bean> <bean class="com.chaycao.InitHelloWorld" /> </beans>
输出:
BeforeInitialization : helloWorld Bean is going through init. AfterInitialization : helloWorld Your Message : Hello World! Bean will destroy now.
Bean 定义继承
子 bean 的定义继承父定义的配置数据。子定义可以根据需要重写一些值,或者添加其他值。Spring Bean 定义的继承与 Java 类的继承无关,但是继承的概念是一样的。可以定义一个父 bean 的定义作为模板和其他子 bean 就可以从父 bean 中继承所需的配置。
例子:
下面是配置文件 Beans.xml ,“helloworld” bean 有两个属性 message1 和 message2 。然后使用 parent 属性把 “helloIndia” bean 定义为 “helloWorld” bean 的孩子,并继承它的属性,同时自己还添加一个属性 message3。
<?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.xsd"> <bean id="helloWorld" class="com.chaycao.HelloWorld"> <property name="message1" value="Hello World!"/> <property name="message2" value="Hello Second World!"/> </bean> <bean id="helloIndia" class="com.chaycao.HelloIndia" parent="helloWorld"> <property name="message1" value="Hello India!"/> <property name="message3" value="Namaste India!"/> </bean> </beans>
下面是 HelloWorld.java 的内容:
public class HelloWorld { private String message1; private String message2; public void setMessage1(String message){ this.message1 = message; } public void setMessage2(String message){ this.message2 = message; } public void getMessage1(){ System.out.println("World Message1 : " + message1); } public void getMessage2(){ System.out.println("World Message2 : " + message2); } }
下面是 HelloIndia.java 的内容:
public class HelloIndia { private String message1; private String message2; private String message3; public void setMessage1(String message){ this.message1 = message; } public void setMessage2(String message){ this.message2 = message; } public void setMessage3(String message){ this.message3 = message; } public void getMessage1(){ System.out.println("India Message1 : " + message1); } public void getMessage2(){ System.out.println("India Message2 : " + message2); } public void getMessage3(){ System.out.println("India Message3 : " + message3); }
下面是 MainApp.java 的内容:
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.getMessage1(); objA.getMessage2(); HelloIndia objB = (HelloIndia) context.getBean("helloIndia"); objB.getMessage1(); objB.getMessage2(); objB.getMessage3(); } }
输出:
World Message1 : Hello World! World Message2 : Hello Second World! India Message1 : Hello India! India Message2 : Hello Second World! India Message3 : Namaste India!
在创建 “helloIndia” bean 的同时并没有传递 message2,但由于 Bean 定义的继承,所以传递了 message2。
Bean 定义模板
在定义一个 Bean 定义模板时,不指定class的属性,将abstract的属性置为 true,如下所示:
<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.xsd"> <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.chaycao.HelloIndia" parent="beanTeamplate"> <property name="message1" value="Hello India!"/> <property name="message3" value="Namaste India!"/> </bean> </beans>
相关文章推荐
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.5 Bean的生命周期
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.5 Bean的生命周期
- Spring学习笔记---2.1-IOC容器解析Bean配置信息
- spring ioc容器的学习笔记4---XmlBeanFactory ioc容器的简单设计原理解析
- Spring 学习笔记(二)—— IOC 容器(BeanFactory)
- [原创]java WEB学习笔记101:Spring学习---Spring Bean配置:IOC容器中bean的声明周期,Bean 后置处理器
- spring源码学习之路---IOC容器初始化要义之bean定义载入
- spring源码学习之路---IOC容器初始化要义之bean定义载入(五)
- spring学习笔记:Spring IOC容器
- spring源码学习之路---IOC容器初始化要义之bean定义载入(五)
- [Spring学习笔记 1 ] Spring 简介,初步知识--Ioc容器详解 基本原理。
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.2 相关Java基础知识 类装载器 反射机制
- Spring学习笔记-Spring容器中的Bean
- 【Spring学习笔记-3.1】让bean获取spring容器上下文(applicationContext.xml)
- Spring学习笔记之IoC容器
- Spring的IoC学习笔记之BeanFactoryPostProcessor
- Spring学习笔记之 Spring IOC容器(二)
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.2 相关Java基础知识 类装载器 反射机制
- Spring学习笔记之 Spring IOC容器(一)
- Spring视频学习笔记(1)IoC容器