Spring基础知识(6)- Spring Bean (三)
Spring后置处理器、Spring Bean继承
1. Spring后置处理器
BeanPostProcessor 接口也被称为后置处理器,通过该接口可以自定义调用初始化前后执行的操作方法。
该接口中包含了两个方法:
postProcessBeforeInitialization() 方法:在 Bean 实例化、属性注入后,初始化前调用。
postProcessAfterInitialization() 方法:在 Bean 实例化、属性注入、初始化都完成后调用。
添加多个后置处理器实现类时,默认情况下 Spring 容器会根据后置处理器的定义顺序来依次调用。也可以通过实现 Ordered 接口的 getOrder() 方法指定后置处理器的执行顺序。该方法返回值为整数,默认值为 0,取值越大优先级越低。
Spring 配置文件(spring-beans.xml),配置格式如下:
1 <?xml version="1.0" encoding="UTF-8"?> 23 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 9 10 class="com.example.Task" init-method="init" destroy-method="destroy"> 11 1312 class="com.example.BeforeTask" /> 14 class="com.example.BeforeTask2" /> 15 16
示例:
1 package com.example; 2 3 import org.springframework.beans.BeansException; 4 import org.springframework.beans.factory.config.BeanPostProcessor; 5 import org.springframework.core.Ordered; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 public class App { 9 public static void main( String[] args ) { 10 11 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml"); 12 Task task = (Task) context.getBean("task"); 13 task.display(); 14 context.close(); 15 16 } 17 } 18 19 class Task { 20 private String name; 21 22 public void setName(String name) { 23 this.name = name; 24 } 25 26 public void display() { 27 System.out.println("Task -> display(): name = " + name); 28 } 29 30 public void init() { 31 System.out.println("Task -> init()"); 32 } 33 34 public void destroy() { 35 System.out.println("Task -> destroy()"); 36 } 37 } 38 39 class BeforeTask implements BeanPostProcessor, Ordered { 40 @Override 41 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 42 System.out.println("BeforeTask -> postProcessBeforeInitialization(): beanName = " + beanName); 43 return bean; 44 } 45 @Override 46 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 47 System.out.println("BeforeTask -> postProcessAfterInitialization(): beanName = " + beanName); 48 return bean; 49 } 50 @Override 51 public int getOrder() { 52 return 0; 53 } 54 } 55 56 class BeforeTask2 implements BeanPostProcessor, Ordered { 57 @Override 58 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 59 System.out.println("BeforeTask2 -> postProcessBeforeInitialization(): beanName = " + beanName); 60 return bean; 61 } 62 @Override 63 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 64 System.out.println("BeforeTask2 -> postProcessAfterInitialization(): beanName = " + beanName); 65 return bean; 66 } 67 @Override 68 public int getOrder() { 69 return 2; 70 } 71 }
输出:
BeforeTask -> postProcessBeforeInitialization(): beanName = task
BeforeTask2 -> postProcessBeforeInitialization(): beanName = task
Task -> init()
BeforeTask -> postProcessAfterInitialization(): beanName = task
BeforeTask2 -> postProcessAfterInitialization(): beanName = task
Task -> display(): name = Bean post processor
Task -> destroy()
2. Spring Bean继承
Spring 中,Bean 和 Bean 之间也存在继承关系,这种继承与 Java 类的继承无关,但是继承的概念是一样的。我们将被继承的 Bean 称为父 Bean,将继承父 Bean 配置信息的 Bean 称为子 Bean。
Spring Bean 的定义中可以包含很多配置信息,例如构造方法参数、属性值。子 Bean 既可以继承父 Bean 的配置数据,也可以根据需要重写或添加属于自己的配置信息。
1) 一般继承
Spring 配置文件(spring-beans.xml)设置继承关系,配置格式如下:
1 <?xml version="1.0" encoding="UTF-8"?> 23 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 9 10 class="com.example.ParentBean"> 11 1412 13 class="com.example.ChildBean" parent="parentBean"> 15 1716
示例:
1 package com.example; 2 3 import org.springframework.context.support.ClassPathXmlApplicationContext; 4 5 public class ExtendsApp { 6 public static void main( String[] args ) { 7 8 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml"); 9 ChildBean childBean = (ChildBean) context.getBean("childBean"); 10 childBean.display(); 11 12 } 13 } 14 15 class ParentBean { 16 private String name; 17 private int age; 18 19 public void setName(String name) { 20 System.out.println("ParentBean -> setName('" + name + "')"); 21 this.name = name; 22 } 23 24 public void setAge(int age) { 25 System.out.println("ParentBean -> setAge('" + age + "')"); 26 this.age = age; 27 } 28 29 public void display() { 30 System.out.println("ParentBean -> display(): name = " + name + ", age = " + age); 31 } 32 } 33 34 class ChildBean { 35 private String name; 36 private int age; 37 38 39 public void setName(String name) { 40 System.out.println("ChildBean -> setName('" + name + "')"); 41 this.name = name; 42 } 43 44 public void setAge(int age) { 45 System.out.println("ChildBean -> setAge('" + age + "')"); 46 this.age = age; 47 } 48 49 public void display() { 50 System.out.println("ChildBean -> display(): name = " + name + ", age = " + age); 51 } 52 }
输出:
ParentBean -> setName('Parent Test')
ParentBean -> setAge('1')
ChildBean -> setName('Child Test')
ChildBean -> setAge('1')
ChildBean -> display(): name = Child Test, age = 1
2) 模板继承
在父 Bean 的定义中,可以不指定 class 属性,这个父 Bean 的 abstract 属性为 true,父类只是个模板。
Spring 配置文件(spring-beans.xml)设置继承关系,配置格式如下:
1 <?xml version="1.0" encoding="UTF-8"?> 23 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 9 10 abstract="true"> 11 1412 13 class="com.example.ChildBean" parent="parentBean"> 15 1716
示例:
与 “ 1) 一般继承” 的代码一样。
输出:
ChildBean -> setName('Child Test (abstract)')
ChildBean -> setAge('2')
ChildBean -> display(): name = Child Test (abstract), age = 2