在看struts2的bean元素配置时一直对这个元素的作用不是很清楚,尽管官方文档说它有两个作用:对象注入和值注入,当时说的都相当抽象。于是上网查了很多资料,并且查了下webwork in action这本书,发现bean元素是struts2里面才引入的,无意间又看了下官方文档中plug-in这节,这才对bean元素的作用有了一点领悟,下面谈下个人理解。在这之前,首先说下struts2中的依赖注入(dependency injection)。
其实依赖注入就是我们常说的反转控制(IoC),在bean配置的那节中一开始就提到,框架使用它自己的依赖注入容器,原文是这样的:Internally, the framework uses its own dependency injection container.这个容器负责装载一些关键的框架对象,因此框架的任何部分都能以一种标准有序的方式被取代、扩展和移去。我查看了文档中overview中的dependency injection这节,struts2内置的IoC容器是基于Google Guice的。我查了下相关资料,发现Google Guice是Google公司最近发布的一个轻量级IoC容器,与spring相比它具有如下特点:1.速度快,号称是srping的100倍;2.无需配置文件,完全依赖jdk5.0的泛型和注释(Annotation)来描述依赖;3.简单代码量少。在Struts2中已经集成了Google Guice容器。创建我们所请求的action的对象以及将页面上文本框中的值按照名字注入到action对象的各个域中去应该都归功于这个Google Guice容器吧,不然我们的action是由谁创建的呢?action中各个属性的值又是谁给我们注入的呢?
现在我们再来谈bean配置到底什么作用的?因为bean的两个作用对象注入和值注入都跟注入扯上了关系,因此我想bean的作用和那个内容的IoC容器是有关系的。接着我们看plugin那节中对sitemesh的讲述。Struts-plugin.xml文件中bean配置是这样的:
<struts>
<bean
class="org.apache.struts2.sitemesh.FreeMarkerPageFilter"
static="true" optional="true"/>
<bean class="org.apache.struts2.sitemesh.VelocityPageFilter"
static="true" optional="true"/>
</struts>
接着有这么一段话:这个两个bean元素,通过使用”static”标记来告诉struts框架在启动的时候将当前的设置和框架对象注入到它们的静态的属性设置器(setter)中。这样的话,FreeMarkerPageFilter类就会得到一个Struts的FreemarkerManager类的实例以及当前的编码设置。原文如下:
The two bean elements, with the "static" flag enabled, tell Struts to inject the current settings and framework objects into static property setters on startup. This allows, for example, the FreeMarkerPageFilter class to get an instance of the Struts FreemarkerManager and the current encoding setting.
怎么去理解呢?打开struts发布包中关于sitemesh的文档,找到FreeMarkerPageFilter这个类,看一下它的静态的属性设置方法,共有下面两个:
static void | setFreemarkerManager(org.apache.struts2.views.freemarker.Freema rkerManager mgr) |
static void | setCustomEncoding(java.lang.String enc) |
上面说框架在启动的时候会将一个Struts的FreemarkerManager类的实例注入到FreeMarkerPageFilter中去,那么这个FreemarkerManager类的实例从哪儿来呢?这正是我们在struts-default.xml定义的一个bean,如下所示:
<bean class="org.apache.struts2.views.freemarker.FreemarkerManager" name="struts"
optional="true"/>
这样的话,bean元素的第一个作用----对象注入就能够很容易的理解了:bean(如FreemarkerManager)由框架容器创建并被注入到其它的内部框架对象(如FreeMarkerPageFilter)中去。那么第二个作用值注入怎么理解呢?前面已经说了,框架会在启动的时候将当前的编码设置注入到FreeMarkerPageFilter中,这个编码设置是我们的一个框架常量,而这正式值注入的作用:有利于那些不是由容器创建的对象接收框架常量(如编码)。这样的话值注入也就能够很容易的理解了。另外,要注意的一点就是,一个bean要想被注入的话,必须定义它的”static”属性。