Spring框架的设计理念与设计模式分析(4)

2020-02-21 22:17

图14.Bean实例创建时序图

还有一个非常重要的部分就是建立Bean对象实例之间的关系,这也是Spring架构的核心竞争力。何时,如何创建它们之间的关系请看下面的时序图:

图15.Bean对象关系建立

3.4.3 IOC容器的扩展点

现在还有一个问题就是如何让这些Bean对象有一定的扩展性,就是可以加入用户的一些操作。那么有哪些扩展点呢?Spring又是如何调用这些扩展点呢?

对Spring的IOC来说,主要有这么几个:BeanFactoryPostProcessor,BeanPostProcessor。它们分别是在构建BeanFactory和构建Bean对象时创建。还有就是InitializingBean和DisposableBean它们分别是在Bean实例创建和销毁时被调用。用户可以实现这些接口中定义的方法,Spring就会在适当的时候调用它们。还有一个是FactoryBean是一个特殊的Bean,可以被用户更多的控制。

这些扩展点通常也是我们使用Spring来完成我们特定任务的地方,如何精通Spring就看你有没有掌握好Spring有哪些扩展点,并且如何使用它们,要知道如何使用它们就要了解Spring内在的机制。可以用下面的比喻来解释:

我们把IOC比作一个箱子,这个箱子里有若干个球的模子,可以用这些模子来造很多种不同的球,还有一个造这些球模的机器,这个机器可以产生球模。BeanFactory就是那个造球模的机器,Bean就是球模,而球模造出来的球就是Bean的实例。那么前面说的几个扩展点又在什么地方呢?

BeanFactoryPostProcessor对应到 当球模被造出来时,你将有机会对其作出适当的修改,也就是它可以帮你修改球模。而InitializingBean和DisposableBean是在球模造球的开始和结束阶段,你可以完成一些

预备和扫尾工作。BeanPostProcessor就可以让你对球模造出来的球进行适当的修正。最后还有一个FactoryBean,它是一个神奇的球模。这个球模不是预先就定型了,而是由你来确定它们的形状,既然你可以确定这个球模的形状,它造出来的球当然是你想要的球了。

3.4.4 IOC容器如何为我所用

前面介绍了Spring容器的创建过程,那Spring能为我们做什么,Spring的IOC容器又能做什么?我们使用Spring必须要首先创建IOC容器,没有它Spring无法工作,ApplicationContext.xml就是IOC容器的默认配置文件,Spring的所有特性功能都是基于这个IOC容器工作的。

IOC它实际上就是为你构建了一个魔方,Spring为你搭好了骨骼框架,这个魔方到底能变出什么好东西出来,这必须要有你的参与。那我们怎么参与?这就是前面说的有哪些扩展点,我们通过实现那些扩展点来改变Spring的通用行为。至于如何实现扩展点来得到我们想要的个性结果,Spring中有很多例子,其中AOP的实现就是Spring本事实现了其扩展点来达到它想要的特性功能,可以拿来参考。

二、 Spring中AOP特性 1. 动态代理的实现

要了解Spring的AOP就必须先了解动态代理的原理,因为AOP就是基于动态代理实现的,动态代理还要从JDK本身说起。

在JDK的java.lang.reflect包下有个Proxy类,它正是构建代理类的入口。这个类的结构如下:

图16. Proxy类结构

从上图发现最后四个是公用方法,而最后一个方法newProxyInstance就是创建代理对象的方法,这个方法的源码如下:

public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) throws IllegalArgumentException{ if (h == null) { }

Class cl = getProxyClass(loader, interfaces); try {

Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h }); throw new NullPointerException();

} catch (NoSuchMethodException e) {

throw new InternalError(e.toString());

} catch (IllegalAccessException e) {

throw new InternalError(e.toString());

} catch (InstantiationException e) {

throw new InternalError(e.toString());

} catch (InvocationTargetException e) { } }

这个方法要有三个参数:ClassLoader用于加载代理类的Loader类,通常这个Loader和被代理的类是同一个Loader类。Interfaces 是被代理的哪些接口;InvocationHandler就是用于执行除了被代理接口中方法外的用户自定义的操作,它也是用户需要代理的最终目的。用户调用目标方法都被代理到InvocationHandler类中定义的唯一方法invoke中。这在后面再详解。

throw new InternalError(e.toString());

下面看看Proxy产生代理类的过程,它构造出来的代理类到底是个什么样子呢,马上揭晓:

图17.创建代理对象时序图

从上图中可以发现正在构造代理类的是ProxyGenerator的generateProxyClass方法。ProxyGenerator类是在sun.misc包下,感兴趣的可以去看它的源码。

假如有这样一个接口,如下: 清单7. SimpleProxy类

public interface SimpleProxy { public void simpleMethod1(); public void simpleMethod2(); }

生成的代理类结构如下:

public class $Proxy2 extends java.lang.reflect.Proxy implements SimpleProxy{ java.lang.reflect.Method m0; java.lang.reflect.Method m1; java.lang.reflect.Method m2;


Spring框架的设计理念与设计模式分析(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:留学生求职除了排队交简历,春招 Career Fair 上你还该做什么?

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: