<>强摘要:
强>
其实我第一次看见这个东西的时候也是不解,代理目标源不就是一个类嘛还需要封装干嘛…
其实<代码> 代码>代理代理的不是<代码>目标> 代码,而是<代码> TargetSource> 代码,这点非常重要,一定要分清楚! ! !
通常情况下,一个代理对象只能代理一个目标,每次方法调用的目标也是唯一固定的目标。但是,如果让代理代理TargetSource,可以使得每次方法调用的目标实例都不同(当然也可以相同,这取决于TargetSource实现)。这种机制使得方法调用变得灵活,可以扩展出很多高级功能,如:单利,原型,本地线程,目标对象池,运行时目标对象热替换目标源等等。
<>强弹簧内置的TargetSource 强>
<强> SingletonTargetSource 强>
公共类SingletonTargetSource实现TargetSource Serializable {/* *目标缓存,使用反射调用。*/私人最终目标对象;//省略无关代码…… @Override 公共对象getTarget () { 返回this.target; }//省略无关代码…… }
从这个目标源取得的目标对象是单例的,成员变量目标缓存了目标对象,每次<代码> getTarget() 代码>都是返回这个对象。
<强> PrototypeTargetSource
强>
公开课PrototypeTargetSource延伸AbstractPrototypeBasedTargetSource {/* * *获取一个新的原型实例为每个调用。 * @see # newPrototypeInstance () */@Override 公共对象getTarget()抛出BeansException { 返回newPrototypeInstance (); }/* * *摧毁给定独立实例。 * @see # destroyPrototypeInstance */@Override 公共空间releaseTarget(对象目标){ destroyPrototypeInstance(目标); }//省略无关代码…… }
每次<代码> getTarget() 代码>将生成<代码> 代码>原型类型的bean,即其生成的bean并不是单例的,因而使用这个类型的<代码> TargetSource> 代码时需要注意,封装的目标bean必须是原型类型的。
<代码> PrototypeTargetSource 代码>继承了<代码> AbstractBeanFactoryBasedTargetSource 代码>拥有了创建bean的能力。
公共抽象类AbstractPrototypeBasedTargetSource延伸AbstractBeanFactoryBasedTargetSource {//省略无关代码……/* * *子类应该调用这个方法来创建一个新的原型实例。 * @throws BeansException如果bean创建失败了 */保护对象newPrototypeInstance()抛出BeansException { 如果(logger.isDebugEnabled ()) { logger.debug(“创建新bean的实例”+ getTargetBeanName () + " ' "); } 返回getBeanFactory () .getBean (getTargetBeanName ()); }/* * *子类应该调用这个方法来摧毁一个过时的原型实例。 * @param摧毁目标bean实例 */保护无效destroyPrototypeInstance(对象目标){ 如果(logger.isDebugEnabled ()) { logger.debug(“摧毁bean的实例”+ getTargetBeanName () + " ' "); } 如果(getBeanFactory()运算符ConfigurableBeanFactory) { ((ConfigurableBeanFactory) getBeanFactory ()) .destroyBean (getTargetBeanName(),目标); } else if(目标instanceof DisposableBean) { 尝试{ ((DisposableBean)目标).destroy (); } 抓住(Throwable特异){ 记录器。警告(“销毁方法> 公共类ThreadLocalTargetSource AbstractPrototypeBasedTargetSource延伸 实现ThreadLocalTargetSourceStats DisposableBean {/* * * ThreadLocal持有目标与当前有关 *线程。与大多数threadlocal,是静态的,这个变量 *是每个线程每ThreadLocalTargetSource类的实例。 */私人最终ThreadLocal