详解常用的详解常用的Spring Bean扩展接口扩展接口
本篇文章主要介绍了一些常用的Spring Bean扩展接口以及它们的简单用法,具有很好的参考价值。下面跟着小编一起来看下吧
前言前言
Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心。
Spring框架运用了非常多的设计模式,从整体上看,它的设计严格遵循了OCP----开闭原则,即:
1、保证对修改关闭,即外部无法修改Spring整个运作的流程
2、提供对扩展开放,即可以通过继承、实现Spring提供的众多抽象类与接口来改变类加载的行为
开卷有益,阅读Spring源码(无需每个类都看得很细,大体流程能梳理出来即可)对于个人水平的提升是帮助非常大的,同时也能在工作中即使发现和解决一些不常见的Spring问题。
不过,本文的目的不是整理Spring的流程,而是通过介绍一些常用的Spring Bean工具类,来让我们可以更好地使用Spring提供给开发者的多种特性,下面让我们开始吧。
InitialingBean和和DisposableBean
InitialingBean是一个接口,提供了一个唯一的方法afterPropertiesSet()。
DisposableBean也是一个接口,提供了一个唯一的方法destory()。
这两个接口是一组的,功能类似,因此放在一起:前者顾名思义在Bean属性都设置完毕后调用afterPropertiesSet()方法做一些初始化的工作,后者在Bean生命周期结束前调用destory()方法做一些收尾工
作。下面看一下例子,为了能明确地知道afterPropertiesSet()方法的调用时机,加上一个属性,给属性set方法,在set方法中打印一些内容:
/**
* @author 五月的仓颉 http://www.cnblogs.com/xrq730/p/5721366.html
*/
public class LifecycleBean implements InitializingBean, DisposableBean
{
@SuppressWarnings("unused")
private String lifeCycleBeanName;
public void setLifeCycleBeanName(String lifeCycleBeanName)
{
System.out.println("Enter LifecycleBean.setLifeCycleBeanName(), lifeCycleBeanName = " + lifeCycleBeanName);
this.lifeCycleBeanName = lifeCycleBeanName;
}
public void destroy() throws Exception
{
System.out.println("Enter LifecycleBean.destroy()");
}
public void afterPropertiesSet() throws Exception
{
System.out.println("Enter LifecycleBean.afterPropertiesSet()");
}
public void beanStart()
{
System.out.println("Enter LifecycleBean.beanStart()");
}
public void beanEnd()
{
System.out.println("Enter LifecycleBean.beanEnd()");
}
}
配置一个spring.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-4.1.xsd">
<bean id="lifeCycleBean" class="org.xrq.bean.lifecycle.LifecycleBean">
<property name="lifeCycleBeanName" value="lifeCycleBean" />
</bean>
</beans>
启动Spring容器,LifecycleBean执行的结果为:
Enter LifecycleBean.setLifeCycleBeanName(), lifeCycleBeanName = lifeCycleBean
Enter LifecycleBean.afterPropertiesSet()
Enter LifecycleBean.beanStart()
Enter LifecycleBean.destroy()
Enter LifecycleBean.beanEnd()
执行结果和我们想的一样,afterPropertiesSet()方法就如同它的名字所表示的那样,是在在Bean的属性都被设置完毕之后,才会调用的属性都被设置完毕之后,才会调用。
关于这两个接口,我总结几点:
1、InitializingBean接口、Disposable接口可以和init-method、destory-method配合使用,接口执行顺序优先于配置
2、InitializingBean接口、Disposable接口底层使用类型强转类型强转.方法名方法名()进行直接方法调用,init-method、destory-method底层使用反射使用反射,前者和Spring耦合程度更高但效率高,后者解除了和Spring之间的
耦合但是效率低,使用哪个看个人喜好
3、afterPropertiesSet()方法是在Bean的属性设置之后才会进行调用,某个Bean的afterPropertiesSet()方法执行完毕才会执行下一个Bean的afterPropertiesSet()方法,因此不建议在afterPropertiesSet()方
法中写处理时间太长的方法
BeanNameAware、、ApplicationContextAware和和BeanFactoryAware
这三个接口放在一起写,是因为它们是一组的,作用相似。
"Aware"的意思是"感知到的",那么这三个接口的意思也不难理解:
1、实现BeanNameAware接口的Bean,在Bean加载的过程中可以获取到该Bean的id
2、实现ApplicationContextAware接口的Bean,在Bean加载的过程中可以获取到Spring的ApplicationContext,这个尤其重要,ApplicationContext是Spring应用上下文,从ApplicationContext中可以获取
包括任意的Bean在内的大量Spring容器内容和信息
3、实现BeanFactoryAware接口的Bean,在Bean加载的过程中可以获取到加载该Bean的BeanFactory
看一下例子:
/**
* @author 五月的仓颉 http://www.cnblogs.com/xrq730/p/5721366.html
*/
public class AwareBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware
{
private String beanName;
private ApplicationContext applicationContext;
private BeanFactory beanFactory;
public void setBeanName(String beanName)
{
System.out.println("Enter AwareBean.setBeanName(), beanName = " + beanName + "");