使用struts2的builder alias机制加载objectFactory
来源:互联网 发布:vscode好看的字体 编辑:程序博客网 时间:2024/05/16 06:48
以下代码基于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中定义了如下的声明:
<
bean
type
=
"com.opensymphony.xwork2.ObjectFactory"
name
=
"spring"
class
=
"org.apache.struts2.spring.StrutsSpringObjectFactory"
/>
<
constant
name
=
"struts.objectFactory"
value
=
"spring"
/>
第一句是声明了一个实现类objectFactory的对象,这就是spring插件所提供的对象容器,而第二句则声明属性struts.objectFactory的值为spring,即key为spring的对象将成为struts2的对象容器。
为什么这样说,我们可以看一下struts2对struts.objectFactory的解释,以下解释摘自struts2中的default.properties:
### if specified, the default object factory can be overridden here
### Note: short-hand notation is supported in some cases, such as "spring"
### Alternatively, you can provide a com.opensymphony.xwork2.ObjectFactory subclass name here
即只要设置了此值,则默认的对象容器,将被改写,那么spring插件所提供的功能就是定义了一个spring实现的对象容器,并且重写了struts2定义,将spring容器再成为struts2的对象容器。
再反过来,我们可以看到struts-default.xml中也定义了如下的容器声明:
<
bean
class
=
"com.opensymphony.xwork2.ObjectFactory"
name
=
"xwork"
/>
<
bean
type
=
"com.opensymphony.xwork2.ObjectFactory"
name
=
"struts"
class
=
"org.apache.struts2.impl.StrutsObjectFactory"
/>
这里定义了两个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容器,并确定对象容器的过程。如下代码所示:
// Set the bootstrap container for the purposes of factory creation
Container bootstrap = createBootstrapContainer();
setContext(bootstrap);
container = builder.create(
false
);
setContext(container);
objectFactory = container.getInstance(ObjectFactory.
class
);
上文中的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(ObjectFactory.
class
, StrutsConstants.STRUTS_OBJECTFACTORY, builder, props);
alias(XWorkConverter.
class
, StrutsConstants.STRUTS_XWORKCONVERTER, builder, props);
alias(TextProvider.
class
, StrutsConstants.STRUTS_XWORKTEXTPROVIDER, builder, props, Scope.DEFAULT);
我们关注的就是第一行,即这里一个,其代码为:
alias(ObjectFactory.
class
, “struts.objectFactory”, builder, props);
需要注意的是,这里的alias和containerProvider所提供的alias还不一样。containerProvider的alias是直接将给定的name定义为别名,而此处的alias是指将给定的name所对应的值定义为别名,相当于中间处了一次处理。为什么处理成这样,其实就是一个扩展的过程。那么我们来看一下相应的实现:
if
(!builder.contains(type)) {
//相当于builder.contains(type,”default”)
String foundName = props.getProperty(key, DEFAULT_BEAN_NAME);
//这里的DEFAULT_BEAN_NAME为struts
if
(builder.contains(type, foundName)) {
builder.alias(type, foundName, Container.DEFAULT_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的builder alias机制加载objectFactory
- struts2的静态注入(ObjectFactory)
- struts2的对象工厂(ObjectFactory)简介
- Struts2中的objectFactory
- struts.objectFactory 由spring管理struts2的Action实例
- activity-alias的使用
- activity-alias的使用
- alias cp的使用
- activity-alias的使用
- activity-alias的使用
- activity-alias的使用
- activity-alias的使用
- activity-alias的使用
- activity-alias的使用
- activity-alias的使用
- activity-alias的使用
- activity-alias的使用
- bean的加载(九)记录创建bean的ObjectFactory
- 当您试图配置 Microsoft Access 2010 数据库用户数据源: 错误消息"Microsoft 访问驱动程序 (*.mdb、 *.accdb) ODBC 驱动程序的安装程序例程未找到。
- C++ 中有用的“计时器”
- hdu4287map应用
- J2EE-SimpleDateFormat的12小时制和24小时制
- android 和linux的多点触摸解析
- 使用struts2的builder alias机制加载objectFactory
- 面试训练丑数
- 12个有趣的C语言面试题
- delphi中array of const 借鉴
- 一个是阆苑仙葩,一个是美玉无瑕
- 检测用户名是否存在(C#代码)
- WWWForm使用demo
- NSIS
- C#教程:深入解析委托与事件的由来