ApplicationContext与BeanFactory关系
ApplicationContext它是扩展BeanFactory接口。
BeanFactory它采取延迟加载的方案,只有真正在getBean时才会实例化Bean
在开发中我们一般使用的是ApplicationContext,真正使用的是其实现类,
FileSystemXmlAppliCationContext 根据文件路径获取
ClassPathXmlApplicationContext 根据类路径获取
AppliCationContext它会在配置文件加载时,就会初始化Bean,并且ApplicationContext它提供不同的应用层的Context实现。例如在web开发中可以使用WebApplicationContext.
IOC获取Bean实例化对象
<bean id="userService" class="com.test.userServiceImpl"/>
//使用Spring的IOC容器;IOC本质是XML配置文件+反射+BeanFactory来实现
//Soring提供一个BeanFactory工厂统一管理Bean,使用其子接口ApplicationContext
//ClassPathXmlApplicationContext:在类路径下根据参数文件名查找ApplicationContext.xml对象
ApplicationContext application=new ClassPathXmlApplicationContext("ApplicationContext");
UserService userService=(UserService)application.getBean("userService");
对于bean的生命周期方法:
第三步与第四步是让Bean了解spring容器。
第五步与第八步 可以针对指定的Bean进行功能增强(在初始化前后执行),这时一般会使用动态代理.
第六步与第十步:通过实现指定的接口来完成init与destroy操作
但是在开发中一般不使用第6步与第10步,原因是我们可以使用第7步与第11步来完成。
第7步与第11步的初始化与销毁操作它无耦合,推荐使用的。但是必须在配置文件中指定初始化与销毁的方法
在xml配置文件中配置相关的bean
<!-- 自定义bean -->
<bean id="testBean" name="bean1" class="com.dubbox.bean.TestBean" init-method="myInit" destroy-method="myDestroy">
<property name="beanStr" value="张三的歌"/>
<property name="beanInt" value="123"></property>
</bean>
<!-- 实现BeanPostProcessor接口的bean,spring ioc容器扩展 -->
<bean id="postProcessor" class="com.dubbox.bean.PostProcessor"></bean>
<!-- spring 注解扫描 -->
<context:component-scan base-package="com.dubbox"></context:component-scan>
Bean分别实现 BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean
/**
*
* @author 张江丰
* BeanNameAware:
* 实现setBeanName方法 设置Bean的id
* ApplicationContextAware/BeanFactoryBean:
* 实现setApplicationContext/setBeanFactory方法 设置ApplicationComtext上下文对象/BeanFactory
* BeanPostProcessor:
* 实现 postProcessBeforeInitialization 和 postProcessAfterInitialization 分别执行初始化执行之前和之后的方法
* InitializingBean:
* 实现afterPropertiesSet方法,进行Bean初始化,在属性封装之后执行
* DisposableBean:
* 实现destroy方法 销毁执行
*
*/
@Scope(value = "singleton")
public class TestBean implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
private String beanStr;
private Integer beanInt;
public String getName() {
return "zhangsan";
}
public String getBeanStr() {
return beanStr;
}
public void setBeanStr(String beanStr) {
this.beanStr = beanStr;
}
public Integer getBeanInt() {
return beanInt;
}
public void setBeanInt(Integer beanInt) {
this.beanInt = beanInt;
}
@Override
public void setBeanName(String name) {
// TODO Auto-generated method stub
System.out.println("调用setBeanName方法:" + name);
}
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
// TODO Auto-generated method stub
this.applicationContext = arg0;
// TestBean bean = (TestBean) applicationContext.getBean("testBean");
System.out.println("调用setApplicationContext方法,获取Spring容器ApplicationContext对象:" + applicationContext);
}
@Override
public void destroy() throws Exception {
// TODO Auto-generated method stub
System.out.println("调用destroy方法,bean被销毁了");
}
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
try {
System.out.println("调用afterPropertiesSet方法,bean初始化执行了");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("bean初始化异常" + e.getMessage());
}
}
//@PostConstruct // 相当于在bean中配置了 init-method="myInit"
public void myInit() {
System.out.println("自定义init执行");
}
//@PreDestroy // 相当与在bean中配置了 destory-method="myDestroy"
public void myDestroy() {
System.out.println("自定义Destory执行");
}
}
自定义类实现BeanPostProcessor接口,分别实现postProcessBeforeInitialization和postProcessAfterInitialization方法,可以在bean初始化前后执行,需要在xml配置文件中配置,是springIOC容器的扩展
BeanPostProcessor接口也叫后置处理器,作用是在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑。注意是Bean实例化完毕后及依赖注入完成后触发的。
/**
* BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口
*
* @author 张江丰
*
*/
public class PostProcessor implements BeanPostProcessor {
@Override // 在bean初始化之前执行
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof TestBean) {
System.out.println("调用postProcessBeforeInitialization方法,在初始化init之前执行:" + beanName + "开始实例化");
}
// 从spring IOC容器中取出bean,使用后必须返回bean对象
return bean;
}
@Override // 在bean初始化之后执行
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof TestBean) {
System.out.println("调用postProcessAfterInitialization方法,在初始化init之后执行:" + beanName + "实例化完成");
}
// 从spring IOC容器中取出bean,使用后必须返回bean对象
return bean;
}
}
junit测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring/applicationContext.xml" })
public class Test1 {
@Test
public void demo1() throws Exception {
ApplicationContext app = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
TestBean tb = (TestBean) app.getBean("testBean");
// TestBean tb = new TestBean();
System.out.println(tb.getBeanStr());
}
}
控制台输出内容
调用setBeanName方法:testBean
调用setApplicationContext方法,获取Spring容器ApplicationContext对象:org.springframework.context.support.ClassPathXmlApplicationContext@63611043: startup date [Fri Feb 07 12:20:13 CST 2020]; root of context hierarchy
调用postProcessBeforeInitialization方法,在初始化init之前执行:testBean开始实例化
调用afterPropertiesSet方法,bean初始化执行了
自定义init执行
调用postProcessAfterInitialization方法,在初始化init之后执行:testBean实例化完成
张三的歌
调用destroy方法,bean被销毁了
自定义Destory执行
由此可见控制台输出顺序和springbean生命周期流程一致,首先执行实例化bean对象,设置对象属性,检查Aware相关接口,如果有类实现BeanPostProcessor接口,在bean初始化init前后执行扩展方法,bean可用状态.