Struts2(XWork)中的Container 一
本文是<<struts2 技术内幕>>的学习笔记
在进行面向对象编程的时候,我们不可避免地要使用继承实现等等java提供的语法支持。但是复杂的对象关系也为对象生命周期的管理带来了至少以下两个问题。
1 程序运行时,应如何双肩我们所需要的对象。
2 当创建一个对象后,如何保证与其相关联的依赖关系也正确的被创建处理。
好在先辈们已经给我们想好了出路------在程序中引入一个额外的编程元素:容器(Container)
对象的生命管理周期
首先我们得引入一个概念-----控制反转(Inverse of Control)
什么是控制反转?从字面上来说大概就是
本来应该由我控制的事情,不再需要我来控制了。至于交给谁来控制,我不需要知道。
举个例子。
public class Person{
private Car car;
public Person(Car c){
this.car=c;
}
public void drive(){
car.drive();
}
}
上面的例子很简单吧,一个人能开车。对于车的产生,需要person自己来创造。
那什么是ioc呢?
public class Person{
private Car car;
public Person(){
//其他代码
}
public void setCar(Car c){
this.car=c;
}
public void drive(){
car.drive();
}
}
就这么简单
本来需要person控制的车的创建,现在不由person来控制了。就是控制反转。
XWork容器的定义
刚才一直再说容器,现在我们就说说strtus2中的容器。
public interface Container extends Serializable {
/**
* Default dependency name.
*/
String DEFAULT_NAME = "default";
/**
* 创建类的实例,并进行注入 在上面说的person与car的例子中
* injcet的参数就应该是person
* object内部声明有@inject的字段和方法都将被注
* 入容器所托管的对象(例如上面说的car)
*/
void inject(Object o);
<T> T inject(Class<T> implementation);
/**
* 根据type与name获得容器中的java类实例
*/
<T> T getInstance(Class<T> type, String name);
/**
* 根据type和默认的name(default)获得容器中的java类实例
*/
<T> T getInstance(Class<T> type);
/**
* 根据type获得所有注册这个type的name
*/
Set<String> getInstanceNames(Class<?> type);
/**
* Sets the scope strategy for the current thread.
*/
void setScopeStrategy(Scope.Strategy scopeStrategy);
/**
* Removes the scope strategy for the current thread.
*/
void removeScopeStrategy();
}
接口中的方法可以分为三类
获取对象实例 getInstance,getInstacneNames
处理对象依赖关系 inject
处理对象的作用范围策略 setScopeStrategy,removeScopeStrategy
并且,容器是一个辅助的编程元素,它在系统中被设计为一个全局的单例的对象。
XWork容器的管辖范围
刚才我们已经初步认识了XWork容器,现在我们看看:XWork到底能管理哪些东西。
1 获取对象实例
getInstance可以获得被容器托管的对象。那么到底哪些对象是容器所托管的呢?
看struts-default.xml里面有三类元素,是容器所托管的
1在bean节点中声明的框架内部的对象
2在bean节点中声明的自定义对象
3在constant节点中声明的系统运行参数
另外还有
在Properties文件里什么歌的系统运行参数
再换句话说,想把自定义的对象纳入容器的管理范围,只需在Sturs/XWork的配置文件里声明即可。
2 对象的依赖注入
就像我们上面说的people与car的关系,people里面需要一个car,而car是通过容器所管理的,那么对people的注入就是container.inject(people)。
inject方法的参数都可以使什么呢?
调用XWork容器的inject方法,能够帮助我们将容器所管理的对象(包括框架的内部元素及系统运行参数)注入到任意的对象实例中。从而建立起任意对象与框架元素沟通的桥梁。
那么系统怎么知道people这个对象里面就需要一个car呢?
public class Person{
@Inject
private Car car;
public Person(){
//其他代码
}
@Inject
public void setCar(Car c){
this.car=c;
}
public void drive(){
car.drive();
}
}
在person里面的car参数或者setCar方法上加上 @Inject标签
我们看看Inject标签的定义
@Target({METHOD, CONSTRUCTOR, FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface Inject {
/**
* Dependency name. Defaults to {@link Container。DEFAULT_NAME}.
*/
String value() default DEFAULT_NAME;
/**
* Whether or not injection is required. Applicable only to methods and
* fields (not constructors or parameters).
*/
boolean required() default true;
}
关于Annotation的使用参见
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
通过容器接口进行对象操作
1 getInstance
public class DefaultUnknownHandlerManager implements UnknownHandlerManager {
protected ArrayList<UnknownHandler> unknownHandlers;
private Configuration configuration;
private Container container;
@Inject
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
build();
}
@Inject
public void setContainer(Container container) {
this.container = container;
build();
}
/**
* Builds a list of UnknowHandlers in the order specified by the configured "unknown-handler-stack".
* If "unknown-handler-stack" was not configured, all UnknowHandlers will be returned, in no specific order
*/
protected void build() {
if (configuration != null && container != null) {
List<UnknownHandlerConfig> unkownHandlerStack = configuration.getUnknownHandlerStack();
unknownHandlers = new ArrayList<UnknownHandler>();
if (unkownHandlerStack != null && !unkownHandlerStack.isEmpty()) {
//get UnknownHandlers in the specified order
// 根据一定顺序获取UnknownHandler实例
for (UnknownHandlerConfig unknownHandlerConfig : unkownHandlerStack) {
//通过容器的getInstance方法获得容器内部脱光光的type为UnknownHandler.class
//name为传入的参数的UnknownHandler
UnknownHandler uh = container.getInstance(UnknownHandler.class, unknownHandlerConfig.getName());
unknownHandlers.add(uh);
}
} else {
//add all available UnknownHandlers
Set<String> unknowHandlerNames = container.getInstanceNames(UnknownHandler.class);
for (String unknowHandlerName : unknowHandlerNames) {
UnknownHandler uh = container.getInstance(UnknownHandler.class, unknowHandlerName);
unknownHandlers.add(uh);
}
}
}
}
.....
}
当然build方法的调用一定是在setContainer与setConfiguration调用之后。
2 inject
public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
private TextProvider getTextProvider() {
if (textProvider == null) {
TextProviderFactory tpf = new TextProviderFactory();
if (container != null) {
container.inject(tpf);
}
textProvider = tpf.createInstance(getClass(), this);
}
return textProvider;
}
@Inject
public void setContainer(Container container) {
this.container = container;
}
}
我们在下面可以看到container.inject(tpf)的参数,也就是TextProviderFactory里面有一个 @Inject标签。
当然getTextProvider之前得先调用setContainer。
public class TextProviderFactory {
private TextProvider textProvider;
@Inject
public void setTextProvider(TextProvider textProvider) {
this.textProvider = textProvider;
}
.....
}
感谢glt
参考资料
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
Struts2(XWork)中的Container 一的更多相关文章
- struts2.0中struts.xml配置文件详解
先来展示一个配置文件 <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration ...
- Struts2/XWork 安全漏洞及解决办法
exploit-db网站在7月14日爆出了一个Struts2的远程执行任意代码的漏洞. 漏洞名称:Struts2/XWork < 2.2.0 Remote Command Execution V ...
- ueditor1.3.6jsp版在struts2应用中上传图片报"未找到上传文件"解决方案
摘要: ueditor1.3.6jsp版在struts2应用中上传图片报"未找到上传文件"解决方案 在struts2应用中使用ueditor富文本编辑器上传图片或者附件时,即使配置 ...
- 请求在Struts2框架中的处理步骤
上图来源于Struts2官方站点,是Struts 2 的整体结构. 一个请求在Struts2框架中的处理大概分为以下几个步骤 1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求 2 ...
- struts2配置文件中action的name属性
struts2配置文件中action的name属性的第一个字符不要加斜杠 <action name="see" class="baoxiuManage_seeAct ...
- Struts2项目中使用Ajax报错
在Struts2项目中使用Ajax向后台请求数据,当添加了json-lib-2.3-jdk15.jar和struts2-json-plugin-2.3.4.1.jar两个包时,在result中配置ty ...
- bootstrap中的.container类定义
bootstrap中的.container类定义 .container{ padding-right:15px; padding-left:15px; margin-right:auto; margi ...
- Struts2框架中使用Servlet的API示例
1. 在Action类中也可以获取到Servlet一些常用的API * 需求:提供JSP的表单页面的数据,在Action中使用Servlet的API接收到,然后保存到三个域对象中,最后再显示到JSP的 ...
- 在Struts2框架中使用Servlet的API
1. 在Action类中也可以获取到Servlet一些常用的API * 需求:提供JSP的表单页面的数据,在Action中使用Servlet的API接收到,然后保存到三个域对象中,最后再显示到JSP的 ...
随机推荐
- ROS机器人程序设计(原书第2版)补充资料 (壹) 第一章 ROS系统入门
ROS机器人程序设计(原书第2版)补充资料 (壹) 第一章 ROS系统入门 书中,大部分出现hydro的地方,直接替换为indigo或jade或kinetic,即可在对应版本中使用. 第一章主要包括R ...
- Web自动化框架LazyUI使用手册(7)--浏览器常用操作API
LazyUI框架中,BrowserEmulator类提供了大量的浏览器操作,常用的API列举如下: 1. 基本操作 /** * Open the URL * 打开一个URL * @param ur ...
- 【伯乐在线】FACEBOOK产品设计总监:设计APP时的14个必考题
最近看到Facebook产品设计总监Julie Zhuo拷问产品的14个问题,非常靠谱.其中有3个问题堪称致命拷问: 1.使用前:这款产品是如何吸引到你的注意力的?2.开始使用:使用这款产品是轻松愉悦 ...
- NSDictionary writeToFile:atomically: 时失败
一.现象:如下图,当NSDictionary调用 writeToFile:atomically: 时,如果容器里面包含的对象(即通过 objectForKey: 拿到的对象),为非property l ...
- Dynamics CRM 权限整理二
接上篇http://blog.csdn.net/vic0228/article/details/50510605,继续列举CRM相关权限 prvReadBusinessUnit privilege(I ...
- 在非ViewController中显示AlertController的方法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 以前我们可以在任何类中使用UIAlertView的show实例 ...
- JVM学习之-栈
JVM栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;JVM堆解决的是数据存储的问题,即数据怎么放.放在哪儿,另外JVM堆中存的是对象.JVM栈中存的是基本数据类型和JVM堆中对象的引用. ...
- 通过一个color创建一个image
使用的地方: [_addButton setBackgroundImage:[UIImage imageWithColor:[[UIColor whiteColor] colorWithAlphaCo ...
- 讲究门面的Request
为什么说Request讲究门面?注意这里所说的门面并非我们常理解的外表的意思,其实是说它使用了门面设计模式,门面的使用主要用于数据安全的考虑.一个大的系统体系的多个子系统之间涉及交互通信.一个系统中的 ...
- 未完成的IT路停在回车键---2014年末总结篇
时间都去哪儿了? 一晃而过,越来越能体会到这个词的真实感.特别是过了二十岁,这种感觉越来越深刻,越来越强烈,犹如小编做公交车的时候一直向后排排倒的香樟树,还记得有首歌叫时间都哪儿了,而 ...