使用struts2的builder alias机制加载objectFactory
2012-09-11 11:05
363 查看
以下代码基于struts2版本2.1.8.1版本分析。
在使用Struts2的过程中,我们都喜欢使用struts2的spring插件来让spring作为struts2的默认对象容器,原理就在于在加载struts2之前先加载spring容器,然后将spring容器加载至applicationContext中,在struts2的objectFactory(称之为对象容器)实现中,找到spring容器并进行各项对象创建工作。
在spring插件中,使用了StrutsSpringObjectFactory类来作为struts2的对象容器,实现过程即除重写objectFactory的各项buildBean方法以符合spring规范之外,其它则就是根据struts2的各项参数设置spring参数(如autoType等)。之所以使用此类作为struts2的对象容器,原因就在于在struts2-spring.jar中的struts-plugin.xml中定义了如下的声明:
第一句是声明了一个实现类objectFactory的对象,这就是spring插件所提供的对象容器,而第二句则声明属性struts.objectFactory的值为spring,即key为spring的对象将成为struts2的对象容器。
为什么这样说,我们可以看一下struts2对struts.objectFactory的解释,以下解释摘自struts2中的default.properties:
即只要设置了此值,则默认的对象容器,将被改写,那么spring插件所提供的功能就是定义了一个spring实现的对象容器,并且重写了struts2定义,将spring容器再成为struts2的对象容器。
再反过来,我们可以看到struts-default.xml中也定义了如下的容器声明:
这里定义了两个objectFactory实现,一个为原生xwork中的objectFactory,另一个则为struts所提供的strutsObjectFactory。其中xwork的key为xwork,而struts的key为struts。
我们知道,在struts2(实际上就是xwork),所确定最终的objectFactory的实现体是需要找一个类型为ObjectFactory,key值为default的实现类,而这2个xml定义中都没有提到default这个key值,那么就是在程序内部所实现了的。
首先看,struts2是如何寻找objectFactory实现的,类DefaultConfiguration中第181行至186行,如何上就是如何创建整个struts2容器,并确定对象容器的过程。如下代码所示:
上文中的builder.create(false)即是创建容器的过程,而container.getInstance(ObjectFactory.class)则是取得(创建)对象容器的过程。那么实际上,在builder.create(false)过程中,实际的对象容器已经确定了,即key为default,类型为ObjectFactory的类已经注入到容器中了。那么这个信息是如何注入的呢,这就归结于builder(即ContainerBuilder)所提供的alias机制了。
什么叫alias?熟悉spring的就知道,其实就是一个别名嘛,我们可以将一个id的aaBean的对象定义一个别名叫bbBean,那么在struts2中,我们也可以将key为spring的对象,定义一个别名叫default!
这就是程序内部实现的原理了,就是找到属性名为struts.objectFactory的属性值,然后将此属性值定义一个别名为default,此后就将此对象作为Struts2容器最终找到的对象了。
那么终需要一个对象来调用builder的alias方法吧,此类就是BeanSelectionProvider,在初始化struts2容器时,此类被作为containerProvider提供给containerBuilder,那么在后面肯定会用到此类了。其实就是在初始化之前提供各项信息给builder,那么它提供的信息是哪些呢,在方法public void register(ContainerBuilder builder, LocatableProperties props)中实现 如下:
我们关注的就是第一行,即这里一个,其代码为:
需要注意的是,这里的alias和containerProvider所提供的alias还不一样。containerProvider的alias是直接将给定的name定义为别名,而此处的alias是指将给定的name所对应的值定义为别名,相当于中间处了一次处理。为什么处理成这样,其实就是一个扩展的过程。那么我们来看一下相应的实现:
首先寻找类型为objectFactory,且key为default的声明,如前所示,肯定找不到的啦。那么就在定义文件中寻找声明为struts.objectFactory的值,在这里我们找到了其值为spring,接下来就将key为spring的定义加个别名为default。在后面就找到了相应对象容器实现了。
需要注意的是,props.getProperty(key, DEFAULT_BEAN_NAME);此句意为在没有找到值的情况下,就使用默认值,而默认值就是struts,意思是需要不存在spring插件,则直接使用key为struts所对象的对象,即StrutsObjectFactory来作为对象容器了。
From:http://www.iflym.com/index.php/code/201204050001.html
在使用Struts2的过程中,我们都喜欢使用struts2的spring插件来让spring作为struts2的默认对象容器,原理就在于在加载struts2之前先加载spring容器,然后将spring容器加载至applicationContext中,在struts2的objectFactory(称之为对象容器)实现中,找到spring容器并进行各项对象创建工作。
在spring插件中,使用了StrutsSpringObjectFactory类来作为struts2的对象容器,实现过程即除重写objectFactory的各项buildBean方法以符合spring规范之外,其它则就是根据struts2的各项参数设置spring参数(如autoType等)。之所以使用此类作为struts2的对象容器,原因就在于在struts2-spring.jar中的struts-plugin.xml中定义了如下的声明:
为什么这样说,我们可以看一下struts2对struts.objectFactory的解释,以下解释摘自struts2中的default.properties:
再反过来,我们可以看到struts-default.xml中也定义了如下的容器声明:
我们知道,在struts2(实际上就是xwork),所确定最终的objectFactory的实现体是需要找一个类型为ObjectFactory,key值为default的实现类,而这2个xml定义中都没有提到default这个key值,那么就是在程序内部所实现了的。
首先看,struts2是如何寻找objectFactory实现的,类DefaultConfiguration中第181行至186行,如何上就是如何创建整个struts2容器,并确定对象容器的过程。如下代码所示:
什么叫alias?熟悉spring的就知道,其实就是一个别名嘛,我们可以将一个id的aaBean的对象定义一个别名叫bbBean,那么在struts2中,我们也可以将key为spring的对象,定义一个别名叫default!
这就是程序内部实现的原理了,就是找到属性名为struts.objectFactory的属性值,然后将此属性值定义一个别名为default,此后就将此对象作为Struts2容器最终找到的对象了。
那么终需要一个对象来调用builder的alias方法吧,此类就是BeanSelectionProvider,在初始化struts2容器时,此类被作为containerProvider提供给containerBuilder,那么在后面肯定会用到此类了。其实就是在初始化之前提供各项信息给builder,那么它提供的信息是哪些呢,在方法public void register(ContainerBuilder builder, LocatableProperties props)中实现 如下:
需要注意的是,props.getProperty(key, DEFAULT_BEAN_NAME);此句意为在没有找到值的情况下,就使用默认值,而默认值就是struts,意思是需要不存在spring插件,则直接使用key为struts所对象的对象,即StrutsObjectFactory来作为对象容器了。
From:http://www.iflym.com/index.php/code/201204050001.html
相关文章推荐
- Struts2使用命名空间后JSP页面无法加载javascript脚本的问题
- 使用Volley三级缓存机制优化ListView加载图片
- Struts2参数的接收 使用DomainObject和ModelDriven
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- 加载XML配置文件的BeanFactory的使用演示
- Apache CXF使用JAXRSClientFactoryBean创建Client时的原则及连接管理机制的Bug
- extjs4.1 和struts2结合使用时延迟加载js,可使用extjs的mvc模式
- 关于spring.net的面向切面编程 (Aspect Oriented Programming with Spring.NET)-使用工厂创建代理(Using the ProxyFactoryObject to create AOP proxies)
- 如何优化加载大位图(BitmapFactory使用系列)
- 使用Struts2的token机制和Cookie来防止表单重复提交
- struts2启动报错 Class: com.opensymphony.xwork2.spring.SpringObjectFactory File: SpringObjectFactory.java
- struts2的对象工厂(ObjectFactory)
- struts2中的constant介绍之struts.objectFactory与spring的整合
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- ireport $P{SUBREPORT_DIR}参数的使用 解决:Could not load object from location 不能加载子报表问题
- WebView的使用小结--加载加速及缓存机制
- Kotlin使用Retrofit进行get请求的方法(懒加载机制)
- bean的加载(九)记录创建bean的ObjectFactory
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- Struts2之Session Token机制理解及使用