有时候会遇到这样的问题:
在我们将一个Bean交给Spring管理的时候,有时候我们的Bean中有某个属性需要注入,但是又不能通过一般的方式注入,什么意思呢?举个栗子:首先我们有个Service,在该Service中有一个属性,但是该属性不支持Spring注入,只能通过Build或者new的方式创建(比如StringBuffer之类的),但是我们想在Spring配置Bean的时候一起将该属性注入进来,这时候该怎么办呢?这时候可以通过实现InitializingBean接口来解决!
@Service
public class DemoService implements InitializingBean{
private StringBuffer stringBuffer;
@Override
public void afterPropertiesSet() throws Exception {
stringBuffer = new StringBuffer();
}
}
上面的列子实现了InitializingBean接口并实现其afterPropertiesSet方法,通过这种方式就可以实现一些比较特殊的注入,当然也可以在afterPropertiesSet方法中添加一些其他逻辑来控制创建的对象。当然除了InitializingBean接口,还有一个类似的接口:DisposableBean ,该接口的作用是在对象销毁时调用。
原理:
首先说说spring的IOC容器初始化过程,首先Spring会定位BeanDefinition资源文件,然后会一个一个的去加载所有BeanDefinition,这里的BeanDefinition就是指的Bean的资源文件,即:在XML中配置的Bean和通过注解装配的Bean,在加载完所有BeanDefinition之后,会将这些BeanDefinition注册到一个HashMap中。到此spring的IOC初始化完成,那么依赖注入发生在哪里呢?在用户第一次向IOC容器索要Bean时才开始依赖注入过程(也可以通过配置lazy-init属性让容器初始化的时候就对Bean预实例化)那究竟afterPropertiesSet()方法的调用是在哪个时间点呢?通过查看该方法上的注释:
Invoked by a BeanFactory after it has set all bean properties supplied (and satisfied BeanFactoryAware and ApplicationContextAware).
可以看到在Bean所有的属性都被注入之后会去调用这个afterPropertiesSet()方法,其实在依赖注入完成的时候,spring会去检查这个类是否实现了InitializingBean接口,如果实现了InitializingBean接口,就会去调用这个类的afterPropertiesSet()方法。所以afterPropertiesSet()方法的执行时间点就很清楚了,发生在所有的properties被注入后。