首先说下这几个接口:
- 1.BeanNameAware
bean实现这个接口可以获取该bean的id - 2.BeanFactoryAware
bean实现这个接口可以获得bean工厂 - 3.InitializingBean
(耦合性高)(注解 @PostConstruct) 类似于init-method 但是在init-method之前执行 - 4.DisposableBean
(耦合性高)(注解 @PreDestroy) 类似于destory-method 但是在destory-method之前执行 - 5.BeanPostProcessor
bean后处理器 可以定义bean初始化之前和初始化之后的两个方法
如下测试程序:
BeanProcessor类
package myspring;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* bean后处理器 bean初始化之前 初始化 初始化之后
*/
public class BeanProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("bean初始化之前执行 ,postProcessBeforeInitialization,BeanPostProcessor -->" + ",object:" + o + ",string:" + s);
return o;
}
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("bean初始化之后执行 ,postProcessAfterInitialization,BeanPostProcessor -->" + ",object:" + o + ",string:" + s);
return o;
}
}
SpringBean类
package myspring;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import java.util.*;
/**
* BeanNameAware 可以获得bean id值
* BeanFactoryAware 可以获得bean工厂
* InitializingBean(耦合性高)(注解 @PostConstruct) 类似于init-method 但是在init-method之前执行
* DisposableBean(耦合性高)(注解 @PreDestroy) 类似于destory-method 但是在destory-method之前执行
*/
public class SpringBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
private String value;
private int num;
private Map<String, String> map;
private Set<String> set;
private String[] strs;
private List<String> list;
private Properties pros;
public SpringBean() {
System.out.println("无参构造方法的执行");
}
public SpringBean(String value) {
this.value = value;
System.out.println("有参构造方法的执行");
}
public void myMethod(){
System.out.println("调用普通方法执行");
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public int getNum() {
return num;
}
public void setNum(int num) {
System.out.println("set方法被执行");
this.num = num;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public Set<String> getSet() {
return set;
}
public void setSet(Set<String> set) {
this.set = set;
}
public String[] getStrs() {
return strs;
}
public void setStrs(String[] strs) {
this.strs = strs;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public Properties getPros() {
return pros;
}
public void setPros(Properties pros) {
this.pros = pros;
}
public void initMethod() {
System.out.println("初始化bean的时候执行,顺序在InitializingBean实现方法后,init-method");
}
public void destoryMethod() {
System.out.println("销毁bean的时候执行,顺序在DisposableBean实现方法后,destory-method");
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("初始化的时候可以注入 bean工厂,需要实现BeanFactoryAware -->" + beanFactory);
}
public void setBeanName(String s) {
System.out.println("初始化的时候可以注入 bean的id,需要实现BeanNameAware -->" + s);
}
public void afterPropertiesSet() throws Exception {
System.out.println("初始化bean的时候执行 @PostConstruct,需要实现InitializingBean");
}
public void destroy() throws Exception {
System.out.println("销毁bean的时候执行 @PreDestroy,需要实现DisposableBean");
}
@Override
public String toString() {
return "SpringBean{" +
"value='" + value + '\'' +
", num=" + num +
", map=" + map +
", set=" + set +
", strs=" + Arrays.toString(strs) +
", list=" + list +
", pros=" + pros +
'}';
}
}
Main方法
package myspring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("app.xml");
SpringBean springBean = (SpringBean) context.getBean("springBean");
springBean.myMethod();
context.registerShutdownHook();
}
}
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- bean 配置 -->
<bean id="springBean" class="myspring.SpringBean" scope="singleton" init-method="initMethod"
destroy-method="destoryMethod">
<!-- 构造方法 -->
<constructor-arg name="value" value="nameValue"/>
<!-- 字符串注入 -->
<property name="num" value="25"/>
<!-- list注入 -->
<property name="list">
<list>
<value>list01</value>
<value>list02</value>
<value>list03</value>
</list>
</property>
<!-- 数组注入 -->
<property name="strs">
<list>
<value>string01</value>
<value>string02</value>
<value>string03</value>
</list>
</property>
<!-- set注入 -->
<property name="set">
<set>
<value>set01</value>
<value>set02</value>
<value>set03</value>
</set>
</property>
<!-- properties注入 -->
<property name="pros">
<props>
<prop key="propkey01">propVal01</prop>
<prop key="propkey01">propVal02</prop>
<prop key="propkey01">propVal03</prop>
</props>
</property>
<!-- map注入 -->
<property name="map">
<map>
<entry key="mapkey01" value="mapvalue01"/>
<entry key="mapkey02" value="mapvalue02"/>
<entry key="mapkey03" value="mapvalue03"/>
</map>
</property>
</bean>
<!-- bean后处理器 类似于filter -->
<bean id="beanProcessor" class="myspring.BeanProcessor"/>
<!-- 包扫描 -->
<!-- <context:component-scan base-package="myspring"/> -->
</beans>
当执行上面的main方法的时候,结果如下:
从上面的执行结果可以看出来,当我们使用spring容器去管理一个bean的时候,从bean的初始化到销毁整个流程如下:
1.执行该对象的构造方法
2.执行set参数注入方法
3.执行BeanNameAware的实现方法获取bean的id
4.执行BeanFactoryAware的实现方法获取bean的工厂
5.执行BeanPostProcessor的postProcessBeforeInitialization处理方法
6.执行InitializingBean的实现方法
7.执行配置的init-method的指定方法
8.执行BeanPostProcessor的postProcessAfterInitialization处理方法
9.执行普通被调用的方法
10.执行DisposableBean的实现方法
11.执行配置的destory-method的指定方法
能用spring配置文件解决的就最好不要用接口实现方式解决,这样能降低代码的被侵入性