携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情
上一篇文章介绍了“方法替换”,用来解决prototype 声明的一个“陷阱”。这篇文章我们来介绍另一个避免“陷阱”的方法。
使用BeanFactoryAware 接口
除了使用“方法注入”的方式来达到“每次调用都让容器返回一个全新的对象实例”的目的之外,还有很多其他的方法。这篇文章我们讲述如何使用BeanFactoryAware 接口来完成这个任务。
如果不使用方法注入,只需要在实现getNewsFetchBean() 方法的时候,保证其内部是调用了BeanFactory 的getBean("newsFetchBean") 就同样可以每次都能取到新的NewsFetchBean 的对象实例。
所以说,现在我们可以换一种思路,让NewsPersister 中持有一个BeanFactory 的实例引用。
这个是有,大显神通的Spring 框架又一次站出来了。Spring 提供了一个BeanFactoryAware 接口,容器在实例化实现了这个接口的bean 的过程中,会自动把容器本身注入到这个bean 中,这样一来,这个bean 就持有了它所处的BeanFactory 的引用。
对于BeanFactoryAware 接口的定义如下:
public interface BeanFactoryAware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
然后我们让NewsPersister 类实现这个接口,这样就会持有这个bean 所处的BeanFactory 的引用,代码如下:
public class NewsPersister implements BeanFactoryAware {
private BeanFactory beanFactory;
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public void persistNews() {
System.out.println("persist bean is: " + getNewsFetchBean());
}
public NewsFetchBean getNewsFetchBean() {
return beanFactory.getBean("newsFetchBean");
}
}
当然了,除了java 代码之外,我们还需要配置文件,简化代码如下:
<bean id = "newsFetchBean" class = "xxxx.NewsFetchBean" singleton = "false"/>
<bean id = "newsPersister" class = "xxxx.NewsPersister"/>
这样一来,我们每次调用getNewsFetchBean 方法的时候,都是从BeanFactory 中重新获取的,重新运行之前那段代码,就会发现,每次的输出结果都是不一致的。
总结
之前我们提到,“方法注入”是通过动态生成子类的方式完成对应功能。其实那个动态生成的子类的内部实现方式的原理与上述过程类似,只不过是细节稍有不同而已。
在学到这个地方的时候,我有一个感触,就是我们在学习某一门技术的时候,不能只看博客,不能看到什么问题仅仅查什么问题,我们要学会看书,跟着数的思路来拓宽我们的知识。否则,就像今天介绍的这个内容,如果从来没遇到过,肯定想都想不到。
之后的文章我们继续介绍其他方法。