一、 Sbeclient_demo
1. struts配置 struts.xml 位置/src/main/resources
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!-- Constants -->
<constant name="struts.devMode" value="false"/> <!-- 属性设置Struts 2应用是否使用开发模式 开发模式更利于调试 -->
<constant name="struts.i18n.encoding" value="UTF-8"/><!--指定Web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法 -->
<constant name="struts.action.extension" value="action"/><!-- 该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。
如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开 -->
<constant name="struts.objectFactory" value="struts"/><!--spring 托管 -->
<!-- xwork/struts -->
<constant name="struts.custom.i18n.resources" value="messages"/><!-- 设置要加载的国际化资源文件,以逗号分隔. -->
<constant name="struts.multipart.maxSize" value="102400000"/><!-- 指定上传文件时的临时目录 大小 -->
<constant name="struts.codebehind.pathPrefix" value="/"/><!-- xwork/struts -->
<constant name="struts.configuration.xml.reload" value="false"/><!-- 设置当struts.xml文件改动时,是否重新加载 -->
<!-- Include Struts defaults -->
<!-- 将struts.xml文件分成多个配置文件,然后在struts.xml文件中使用<include>标签引用这些配置文件 struts-default.xml是系统的内置的配置文件,其中包含了很多的内置的拦截器的定义 -->
<include file="struts-default.xml"/>
<include file="struts-plugin.xml"/>
<!-- Configuration for the default package. extends="struts-default" -->
<package name="default" extends="json-default">
<!--本处只定义了一个defaultStack拦截器 interceptor-stack是一堆拦截器组成的一个拦截器栈。也可以当拦截器使用.interceptor-ref是指定某个action使用哪一个拦截器,可以是一个interceptor,也可以是一个interceptor-stack。 也可以自定义拦截器 需要 继AbstractInterceptor类 param 指定拦截的方法可以参考 http://www.iteye.com/problems/62435-->
<interceptors>
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">cancel,execute,delete,edit,list</param>
</interceptor-ref>
<! -- <interceptor-ref name="json" /> -->
</interceptor-stack>
</interceptors>
<!-- 定义在<action>元素里面的<result>我们可以称之为局部<result>,除此之外我们还可以定义全局的<result>,这些全局的<result>会被多个<action>所共享。
框架会首先寻找嵌套在<action>元素中的<result>,如果没有匹配的就去全局<result>中寻找。全局的<result>列表定义在<global-results> -->
<global-results>
<result name="dataAccessFailure">dataAccessFailure.jsp</result>
<result name="error">error.jsp</result>
<result name="loginLink" type="freemarker">/WEB-INF/pages/loginalert.ftl
</result>
</global-results>
<!-- name 否 用来表示该异常配置信息
result 是 指定发生异常时显示的视图信息,这里要配置为逻辑视图
exception 是 指定异常类型 -->
<global-exception-mappings>
<exception-mapping exception="org.springframework.dao.DataAccessException"
result="dataAccessFailure"/>
</global-exception-mappings>
<!-- Action 配置中的各个默认值 action的class->ActionSupport action的method->execute result的name->SUCCESS=success
Action中的result的各种转发类型 type ①dispatcher:默认的,内部请求转发 ②redirect:浏览器重定向 ③redirectAction:重定向到另一个action ④plainText:原样输出网页源代码,不执行Jsp
本项目配置type="freemarker" freemarker为模版引擎
配置中${属性名} 对应action中的属性 <param name="方法">值 </param> 为action 进行方法的注入值
Action中 name=”helloworld_*” method=”{1}” 如果请求的url尾是helloworld_execute,调用的是execute方法 如果是 helloworld_other,调用的是 other 方法
http://www.cnblogs.com/yinger/archive/2011/07/25/2116707.html
-->
<!--<action name="login" class="com.travelsky.linkoSky.web.action.LoginAction"
method="loginPage"> -->
<!--<result name="success" type="freemarker">/WEB-INF/pages/login.ftl</result> -->
<!--</action> -->
<action name="loginIn" class="com.travelsky.linkoSky.web.action.LoginAction"
method="doLogin">
<result name="login" type="freemarker">/error/login_error.ftl</result>
<result name="success">/index.html</result>
</action>
……………………………………….更多actions
</package>
</struts>
1. web.xml 位置src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<!-- 加载顺序 context-param -> listener -> filter -> servlet 参考 http://www.java3z.com/cwbwebhome/article/article8/81136.html -->
<!-- filter 过滤器元素将一个名字与一个实现 javax.servlet.Filter接口的类相关联。 -->
<!-- filter是个request到达servlet之前预处理request,也可以在离开servlet时处理response. 是一个”servlet chaining”(servlet 链).一个filter 包括:
1. 在servlet被调用之前截获;2. 在servlet被调用之前检查servlet request;3. 根据需要修改request头和request数据;4. 根据需要修改response头和response数据;
5. 在servlet被调用之后截获. login-filter为本系统定义的一个filter 包com.travelsky.filter.LoginFilter -->
<!-- 多个过滤器 会用FilterChain来决定次序 -->
<!-- <filter-name>子元素定义了—个过滤器的名字,<filter-class>指定了由容器载入的实际类,<init-param>子元素为过滤器提供初始化参数 -->
<!-- 参考 http://www.cnblogs.com/jinzhengquan/archive/2011/02/16/1955778.html -->
<filter>
<filter-name>login-filter</filter-name>
<filter-class>com.travelsky.filter.LoginFilter</filter-class>
</filter>
<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>org.csair.sshframework.app</param-value>
</init-param>
</filter>
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class>
</filter>
<!-- 一旦命名了一个过滤器,就要利用filter- mapping元素把它与一个或多个servlet或JSP页面相关联 -->
<!-- <filter-mapping> 主要由<filter-name>,<servlet-name>和<url-pattem>子元素组成。<servlet-name>将过滤器映射到一个或多个Servlet上,
<url-pattem>将过滤器映射到—个或多个任意特征的URL的JSP页面。 /* 表示 所有的请求都会拦截 -->
<filter-mapping>
<filter-name>login-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- context-param,它用于向 ServletContext 提供键值对,即应用程序上下文信息。我们的 listener, filter 等在初始化时会用到这些上下文中的信息 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:applicationContext.xml
</param-value>
</context-param>
<!--<listener>-->
<!--<listener-class>com.travelsky.listener.StartUpListener</listener-class>-->
<!--</listener>-->
<!--使用ContextLoaderListener监听器。这个监听器中会有一个ContextLoade类用来获取这个context-param 配置文件中的信息contextConfigLocation spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list>
<!-- 在返回特定HTTP状态代码时,或者特定类型的异常被抛 出时,能够制定将要显示的页面。http://blog.csdn.net/ly5156/article/details/6950081 -->
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/error.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.NullException</exception-type>
<location>/error.jsp</location>
</error-page>
</web-app>
2. spring配置文件 applicationContext.xml位置/src/main/resources.
3. accounts.properties 或者 jdbc.properties 位置/src/main/resources
4. freemaker模板
struct 赋值给html页面是这样的,setAttribute(“name”,”wenjiabao”);
页面 <html:text property="name" value="${requestScope.name}"/>
struts 中在struts.xml声明了type类型为freetype表示使用fremake模版。Action使用getxxxxxx(){};将xxxxxx变量形式向fremake模版.ftl赋值。
${…}是模版中的变量,<#--和--> 表示是注释,
Freemaker if…else指令 : 是以 <#指令>开始的标签 以</#指令>结束的标签 <#if animals.python.price < animals.elephant.price> 输出内容1 <#else> 输出内容2 </#if>
freemaker循环指令 :<#list animals as being> <tr><td> ${$being.name}</td></tr> </#list>
freemaker 包含指令include : <#include “../../derectory/test.html”>
freemaker 不允许< <#与指令之间有空格 特殊符号转义使用 / /”双引号 /’单引号
java action处理:freemarker.template.Configuration 创建configuration实例
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates")); //模版存放的目录
cfg.setObjectWrapper(new DefaultObjectWrapper()); //默认
/* 在整个应用的生命周期中,这个工作你可以执行多次 */
/* 获取或创建模板*/
Template temp = cfg.getTemplate("test.ftl");
/* 创建数据模型 */
Map root = new HashMap();
root.put("user", "Big Joe");
Map latest = new HashMap();
root.put("latestProduct", latest);
latest.put("url", "products/greenmouse.html");
latest.put("name", "green mouse");
/* 将模板和数据模型合并 */
Writer out = new OutputStreamWriter(System.out);
temp.process(root, out);
out.flush();
注意:
为了简单起见,这里压制了异常(在方法签名中声明了异常,译者注),而在正式运行的产品中不要这样做。
5. com.opensymphony.xwork.ActionContext(SerletActionContext)
ActionContext是action对象执行的上下文,属于map类型,存放的是Action在执行的需要用到的对象,如:请求的参数(Parameter),会话(Session)、Servlet上下文(ServletContext)、本地化信息(Location)等。
得到请求信息中的Usename如下:
Map session = ActionContext.getContext().getSession();//取得httpSession
ActionContext context = ActionContext.getContext(); //取得当前的ActionContext对象
Map params = context.getParameters();
String username = (String) params.get(“username”);
ServletActionContext对象继承ActionContext,提供了直接与JavaServelet相关对象的访问。可以取得如下对象:
javax.servlet.http.HttpServletRequest:HTTPservlet请求对象
javax.servlet.http.HttpServletResponse;:HTTPservlet相应对象
javax.servlet.ServletContext:Servlet 上下文信息
javax.servlet.ServletConfig:Servlet配置对象
javax.servlet.jsp.PageContext:Http页面上下文
二、 B2bDataserver
6. spring配置文件 applicationContext.xml位置/src/main/resources
7. spring 注入注释使用
@Autowised 它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去.
当@Autowired没有匹配的bean时,会爆出错来的抛出 BeanCreationException 异常。可以@Autowired(required=false)时,就不会抛出上述异常。
当@Autowired匹配多个bean时,也会抛出BeanCreationException 异常。可以使用@qualifier 来指定使用哪个名字(即配置 中的id值)的bean对象。如:
@Autowired
public void setOffice(@Qualifier("office")Office office) {this.office = office;}
@resource 作用与@Autowired 但@Resourse默认通过name注入,而@Autowired通过type注入。
@Resource 有两个属性是比较重要的,分别是 name 和 type,Spring 将 @Resource 注释的 name 属性解析为 Bean 的名字,而 type 属性则解析为 Bean 的类型。所以如果使用 name 属性,则使用 byName 的自动注入策略,而使用 type 属性时则使用 byType 自动注入策略.
@Resourse驱动需要注册bean <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
@Postconstruct 和@Predestroy标签 @Postconstruct 在类初始化后进行调用,@Predestroy是类destroy之前调用。此两个参数是用在方法前标注的。在xml配置中是对应init-method和destroy-method两个方法。
在spring的xml配置文件中<beans>配置 <context:annotation-config/>。 将隐式地向 Spring 容器注册 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及 equiredAnnotationBeanPostProcessor 这 4 个 BeanPostProcessor。
@Component 是对应xml配置中的一个bean配置. 其@SCOPE属性为single 也可以指定@Scope为prototype,这样每次返回的每次实例都是新的
@Scope("prototype")
@Compnent(“boss”) //将bean Boss名称定义为boss
Public class Boss{}
扫描过滤类:
过滤器类型 说明
注释 假如 com.baobaotao.SomeAnnotation 是一个注释类,我们可以将使用该注释的类过滤出来。
类名指定 通过全限定类名进行过滤,如您可以指定将 com.baobaotao.Boss 纳入扫描,而将 com.baobaotao.Car 排除在外。
正则表达式 通过正则表达式定义过滤的类,如下所示: com\.baobaotao\.Default.*
AspectJ 表达式 通过 AspectJ 表达式定义过滤的类,如下所示: com. baobaotao..*Service+
@Servive @Repository @Controller分别对应持久层,业务层,和控制层,作用和@Component等同。
参考:http://www.ibm.com/developerworks/cn/java/j-lo-spring25-ioc/
@SuppressWarnings("unchecked") 屏蔽某些编译时的警告信息,在强制类型转换的时候编译器会给出警告
8. Spring取bean
可以使用 BeanFactory factory = new XmlBeanFactory(resource); factory.getBean(bean名称); 也可以使用 appContext = new ClassPathXmlApplicationContext("springDataservice/applicationContext.xml"); appContext。getBean(bean名称);
9. 线程
线程、线程组、什么是幽灵线程(为其他线程提供服务资源数据的线程)
新线程态,可运行态,非运行态(sleep suspend wait 等待1/o),死亡态
Java中建立线程有两种方法,一种是继承Thread类,另一种是实现Runnable接口。提出采用Runnable接口。
java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
答:有两种实现方法,分别是继承Thread类与实现Runnable接口
用synchronized关键字修饰同步方法
反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
三、 设计模式 (headfirst)
10. 工厂模式
可以利用静态方法定义为简单工厂的方法.也是常见技巧。
用工厂类初始化客户类(如比萨店)。
依赖倒置原则:具体类最好依赖抽象,不要依赖具体类!最好在驱动类中来实例化具体类!
不管是高层组件还是低层组件,依赖抽象是最好的设计原则!
怎么做到上述原则:类中变量不可以持有具体类(即使用new一个对象),使用工厂类实现。
不要让类派生来自具体类。可以不要覆盖基类中已经实现的方法。
抽象工厂模式:使客户类提供接口创建一系列的相关和依赖的对象家族,而不需要指定具体类.
11. 单件模式
定义:确保一个类只有一个实例,并提供一个全局访问点。
Java 使用 static synchronized 来对实例对象的方法进行修饰,不允许多个线程执行此方法,但同步一个方法使性能下降100倍,如果使用volatile 修饰唯一的实例对象时,volatile关键词可以确保:对象被初始化成单列对象时,只有第一次彻底检查对象是否为空执行synchronized 里面的代码 (参见73页)。
volatile定义:如果一个字段被声明成volatile,java线程内存模型确保所有线程看到这个变量的值是一致的。
单件模式确保有一个静态变量和一个静态方法,一个私有构造方法。
12. 命令模式-封装调用
将命令单独做成一个类,将对象与命令解耦合,在测试驱动时再传递一个对象个命令对象来驱动命令的执行,命令类里面装载一个要执行它的对象。命令可以达到多个对象的复用,也易于扩展命令类。
空命令类:初始化使用命令的类的对象,里面的方法皆为空方法。
为了更好的管理命令类对象和使用的类,我们也许还需要一个管理类。
宏命令:一次执行一组命令。将一组命令封装到一个宏命令类里面一起执行。宏命令也需要传入一个执行命令的对象。
命令模式的应用:队列请求,包括:工作队列,线程池,日程安排
工作队列:请求命令类对象不停的往工作队列填充命令类对象,处理命令类的对象的线程在另外一端取出命令,分发给相应处理此命令的线程来执行(excute())。完成后,将命令在队列中删除,然后继续取命令对象,如此循环不停的工作,主线程取出来命令后,分发给相应处理此命令的线程来完成其命令的请求。
Web服务器模式即为此模式架构。
命令模式的定义:将请求封装成对象,这可以让你使用不同的请求,日志,队列来参数化其他对象。
13. 适配器模式
适配器模式类的书写:1。需要先继承要转换成的类型接口,2.将要被转化的类的对象传入本类中。3进行适配。目的是使两个不同的类(对象)通过适配器转化后,可以使用同样的api 实现共同的目标接口,达到同样的使用效果。
定义:将一个类转化成客户期望的类的接口,可以将两个类亲密无间的合作工作。客户只看到目标接口。
Java 系统 enumeration类(不存在remove()方法)适配成iterator类类使用,iterator类中remove 方法声明为unsupportoperationException类型。EnumerariotnIterator适配器中 public void remove( throw new unsupportoperationException(); )
14. 外观模式
定义:将接口变得更简单。封装接口,以一种简单的表现形式展现。
15. 装饰模式
类应该对扩展开放,对修改关闭,通俗设计类时应该允许对其扩展,不要对其进行修改。
16. 观测者模式
定义:定义了一对多的关系,当主题对象发生改变时,观测者对象可以得到更新的消息。也可以取消观察。是定义了一系列对象的一对多的关系。
在观测者中引用主题来注册或反注册观测者自身,在主题对象中引用来观测者的方法把数据传给观测者对象。
17. 模版方法模式—封装算法
模版的基类一般是一个抽象类,其实是一个算法模版,定义了算法的步骤,可以起到规范算法的作用,但同时又把一些步骤放到子类中去实现的,把公用的方法放里面,不共用的方法声明空方法,继承类各自实现空的方法,来实现做到自己的业务
钩子方法:是模版类中的空方法,由子类继承来实现的方法,也由子类决定是否实现,一般是实方法,钩子的作用也可以作为类中的条件控制语句。
模版模式中方法:钩子方法,抽象方法,一般其他方法,若子类必须实现的方法,使用抽象方法,可以实现也可以不用实现的话,则可以钩子方法。
好莱坞原则:别调用我们(别打电话给我们),我们会调用你的(高层组件对待低层组件的原则)。
Java例子:Java 数组使用了模版类钩子实现,sort()中方法merger()方法调用钩子compareTo()来的。compareTo()来自接口conparable接口,故需要排序的类需要继承comparable接口并且在类中compareTo()方法,此方法是实现两个对象的比较,返回两个对象的大于,等于或者小于。
Java例子 jframe:swing容器,jframe是最基本的swing的容器,中有paint()方法,是一个钩子方法,什么事情都不做,覆盖paint()方法画出你需要的图形。
Java例子:applet程序,此程序也是使用钩子的,其钩子函数们为:init(),stop(),destroy(),paint(),start();
18. 迭代器和组合模式
书本例子(221):菜单类使用array 菜单类2使用arrayList 类型:统一起来使用iterator,写一个iterartor类来继承接口iterator,然后传入数组,将数组实现hasNext(),和next()方法.(,同样也需要将arrayLIst也如前一个一样实现一个iterator.)在array数组类添加此类的对象函数创建一个iterator对象,然后在客户端waitress类里面调用菜单类的createrIterator来创建一个itrator对象就可以统一的使用。实际上添加了两个迭代器,然后在原来的类里面添加两个转化成迭代器的方法,就可以统一的使用!
使用java的系统接口iterator来改良上述的设计(java.util.iterator),把创造迭代器放在menu接口,让原来的两个菜单来继承现在的菜单接口,在waitress类中就可以使用统一的menu接口声明原来的两个菜单类,好处是使waitress类针对接口编程,不再是针对实现编程。
定义:提供一种统一的方法顺序方法聚合元素内的各个对象,但又不会暴露聚合类内的内部表示
这样代码更容易维护,也易于扩展。
设计原则:一个类应该只有一个引起变化的原因.如管理聚合类,和遍历聚合类就为两个变化的原因。其中一个变化整个类也变化,因此最好将其中一个变化的原因的责任分配给另一个新的类来处理!减少了耦合。
19. 组合模式---承迭代模式
定义:允许你将对象组合成树形结构来表现“整体/部分”层次结构,组合可以让客户以一致的方式来处理个别对象和对象组合。
承上7)上列菜单例子解说,现在菜单需求为:已经是一个树形菜单。设计变更为:设计一个menuComponent抽象类,拥有子菜单和菜单节点的方法和属性并且还有一个创造迭代器接口的方法,其方法初始化都为抛出异常 void ….{throw new UnsupportOprationException ;};其子菜单类和菜单节点类都继承上述的类,将相应的方法实现,遍历时可以使用之前的创建迭代器的接口,
下面是菜单的遍历的代码:
public void print() {
System.out.print("\n" + getName());
System.out.println(", " + getDescription());
System.out.println("---------------------");
Iterator iterator = menuComponents.iterator();
//本段代码需要结合下面的CompositeIterator类来看
while (iterator.hasNext()) {
MenuComponent menuComponent =
(MenuComponent)iterator.next();
menuComponent.print();
}
}
下面是实现了遍历的树的菜单的迭代器类。
package headfirst.composite.menuiterator;
import java.util.*;
public class CompositeIterator implements Iterator {
Stack stack = new Stack();
public CompositeIterator(Iterator iterator) {
stack.push(iterator);
}
public Object next() {
if (hasNext()) {
Iterator iterator = (Iterator) stack.peek();
MenuComponent component = (MenuComponent) iterator.next();
if (component instanceof Menu) {
stack.push(component.createIterator());
}
return component;
} else {
return null;
}
}
public boolean hasNext() {
if (stack.empty()) {
return false;
} else {
Iterator iterator = (Iterator) stack.peek();
if (!iterator.hasNext()) {
stack.pop();
return hasNext();
} else {
return true;
}
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
空迭代器:菜单内没有任何可以迭代的数据;package headfirst.composite.menuiterator;
import java.util.Iterator;
public class NullIterator implements Iterator {
public Object next() {
return null;
}
public boolean hasNext() {
return false;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
20. 状态模式—状态机
四、 Java知识
1. Map遍历
GfMetaData metaData = new GfMetaData();
Iterator iter = TKTDataContextListener.gfTktDataFields.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
companyCode = entry.getKey().toString();
metaData = (GfMetaData) entry.getValue();
}
Iterator item = TKTDataContextListener.gfTktDataFields.keySet().iterator();
while (item.hasNext()) {
companyCode = item.next().toString();
metaData = (GfMetaData) map.get(companyCode);
}
2. Maven 编译命令
先进入工程,然后 cmd,输入命令 maven clean install –Dmaven.test.skin=true 编译以后将在target下找到包。
3. Marshaller
将一个对象转换成xml
4. Java.util.properties
Properties是一个以”key=value”值来存储值的类。
java.lang.Object java.util.Dictionary<K,V> java.util.Hashtable<Object,Object> java.util.Properties
主要方法有 load(Properties输入流对象),keySets(); get(key值)
作用主要是用来对常见的properties类型的文件处理
五、 Mule学习
1. muleIDE安装
Eclipse 3.5/3.6/3.7 (Galileo/Helios/Indigo) 按以下步骤安装Mule IDE:
1. 进入eclipse,点击菜单Help > Install New Software.
2. 点击Add 按钮,弹出的的对话框,在Location中输入 http://dist.muleforge.org/mule-ide/updates-2.1.x/ 后按Enter。Mule IDE就会出现在可用软件列表里。
3. 选中Mule IDE后点击Next. Eclipse将会运行一会,完成后点击Next。
4. 浏览Mule IDE license, 选择accept the license, 然后点击Finish。
5. 点击Yes重启Eclipse.
2. Esb简介
功能:在服务与服务之间路由消息,在请求者与服务者之间转换协议或转换协议格式,处理来自异构的事物。
3. Mule管理
4. Mule消息流程
Appliction channel => MessageReceive|Connect|Transformer =>InboundRounter => interpter|lifecycle Adapt =>
UMO Componet=>
Outbound Rounter=> MessageReceive|Connect|Transformer => interpter|lifecycle Adapt => Appliction channel
5. Mule服务器端
端点endpoint,使用什么协议。
UMO compont
Mule管理器
Mule服务器通知 Mule事件 Mule事务
6. Mule客户端
第三条包括对数据库的配置和支持。
MuleClient muleClient = new MuleClient(muleContext);
//Create client for existing Mule instance context
String actualHash =
muleClient.send("vm://Md5FileHasher.In",tempFileName, null).getPayload();//Use client to perform synchronous send to endpoint
assertEquals(expectedHash, actualHash);
实例2:
MuleClient muleClient = new MuleClient(false);//Creates empty Mule instance and client connected to it
MuleMessage response =muleClient.send(
"http://www.google.com/finance/historical?q=NASDAQ:GOOG&histperiod=weekly&output=csv",null, null);// Performs synchronous send
using HTTP transport
String payload = response.getPayloadAsString();//Retrieves result of
HTTP call as string
muleClient.dispose();//Disposes client
实例3
MuleClient muleClient =new MuleClient("conf/raw-jms-muleclient-config.xml"); // Creates client and configures MuleStarts theMule instance
muleClient.getMuleContext().start(); //Performs synchronousread using JMStransport
// Disposes configured Mule instance, then client
MuleMessage response = muleClient.request("jms://"+ queueName+ "?connector=amqConnector", 1000);
muleClient.getMuleContext().dispose();
muleClient.dispose();
7. Mulecontext api
Controlling a Mule instance: muleContext.start();muleContext.dispose();
Reading the configuration
Accessing statistics
Looking up the registry
Service service = muleContext.getRegistry().lookupService(serviceName);
service.getStatistics().logSummary(new XMLPrinter(xmlStatisticsWriter));
8. MuleEvent contaxt api
Prospecting messages
A Mule message object contains properties and a payload, and optionally an exception, some attachments, and cached values.
Influencing message processing
9. Transformer
Transformers can be chained to cumulate their effects.:
Byte[]=>XSL-T transformer=> Byte[]=>object to string transformer =>String => object To JMs message=>JMs text meessage
10. Router
=> filer + Endpoint =>
filer + Endpoint ROUNT =>
filer + Endpoint=>
一个实例的流程:
=>Inbound endpoint HTTP port => Inbound router => XSL transformer(Byte[] to BYTe[] )=> component => outbound pass-through route=>outbound endpoint JMS destination=>
11. Mule Action
参考文章http://my.oschina.net/moon/blog/40125
六、 Skybus
AbstractTransformer doTransform()方法是抽象类。
notifications 元素: These notifications are generated when specific events occur inside Mule, such as when an instance starts or stops, when an exception has been caught, or when a message is received or dispatched.5
1. struts配置 struts.xml 位置/src/main/resources
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!-- Constants -->
<constant name="struts.devMode" value="false"/> <!-- 属性设置Struts 2应用是否使用开发模式 开发模式更利于调试 -->
<constant name="struts.i18n.encoding" value="UTF-8"/><!--指定Web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法 -->
<constant name="struts.action.extension" value="action"/><!-- 该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。
如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开 -->
<constant name="struts.objectFactory" value="struts"/><!--spring 托管 -->
<!-- xwork/struts -->
<constant name="struts.custom.i18n.resources" value="messages"/><!-- 设置要加载的国际化资源文件,以逗号分隔. -->
<constant name="struts.multipart.maxSize" value="102400000"/><!-- 指定上传文件时的临时目录 大小 -->
<constant name="struts.codebehind.pathPrefix" value="/"/><!-- xwork/struts -->
<constant name="struts.configuration.xml.reload" value="false"/><!-- 设置当struts.xml文件改动时,是否重新加载 -->
<!-- Include Struts defaults -->
<!-- 将struts.xml文件分成多个配置文件,然后在struts.xml文件中使用<include>标签引用这些配置文件 struts-default.xml是系统的内置的配置文件,其中包含了很多的内置的拦截器的定义 -->
<include file="struts-default.xml"/>
<include file="struts-plugin.xml"/>
<!-- Configuration for the default package. extends="struts-default" -->
<package name="default" extends="json-default">
<!--本处只定义了一个defaultStack拦截器 interceptor-stack是一堆拦截器组成的一个拦截器栈。也可以当拦截器使用.interceptor-ref是指定某个action使用哪一个拦截器,可以是一个interceptor,也可以是一个interceptor-stack。 也可以自定义拦截器 需要 继AbstractInterceptor类 param 指定拦截的方法可以参考 http://www.iteye.com/problems/62435-->
<interceptors>
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">cancel,execute,delete,edit,list</param>
</interceptor-ref>
<! -- <interceptor-ref name="json" /> -->
</interceptor-stack>
</interceptors>
<!-- 定义在<action>元素里面的<result>我们可以称之为局部<result>,除此之外我们还可以定义全局的<result>,这些全局的<result>会被多个<action>所共享。
框架会首先寻找嵌套在<action>元素中的<result>,如果没有匹配的就去全局<result>中寻找。全局的<result>列表定义在<global-results> -->
<global-results>
<result name="dataAccessFailure">dataAccessFailure.jsp</result>
<result name="error">error.jsp</result>
<result name="loginLink" type="freemarker">/WEB-INF/pages/loginalert.ftl
</result>
</global-results>
<!-- name 否 用来表示该异常配置信息
result 是 指定发生异常时显示的视图信息,这里要配置为逻辑视图
exception 是 指定异常类型 -->
<global-exception-mappings>
<exception-mapping exception="org.springframework.dao.DataAccessException"
result="dataAccessFailure"/>
</global-exception-mappings>
<!-- Action 配置中的各个默认值 action的class->ActionSupport action的method->execute result的name->SUCCESS=success
Action中的result的各种转发类型 type ①dispatcher:默认的,内部请求转发 ②redirect:浏览器重定向 ③redirectAction:重定向到另一个action ④plainText:原样输出网页源代码,不执行Jsp
本项目配置type="freemarker" freemarker为模版引擎
配置中${属性名} 对应action中的属性 <param name="方法">值 </param> 为action 进行方法的注入值
Action中 name=”helloworld_*” method=”{1}” 如果请求的url尾是helloworld_execute,调用的是execute方法 如果是 helloworld_other,调用的是 other 方法
http://www.cnblogs.com/yinger/archive/2011/07/25/2116707.html
-->
<!--<action name="login" class="com.travelsky.linkoSky.web.action.LoginAction"
method="loginPage"> -->
<!--<result name="success" type="freemarker">/WEB-INF/pages/login.ftl</result> -->
<!--</action> -->
<action name="loginIn" class="com.travelsky.linkoSky.web.action.LoginAction"
method="doLogin">
<result name="login" type="freemarker">/error/login_error.ftl</result>
<result name="success">/index.html</result>
</action>
……………………………………….更多actions
</package>
</struts>
1. web.xml 位置src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<!-- 加载顺序 context-param -> listener -> filter -> servlet 参考 http://www.java3z.com/cwbwebhome/article/article8/81136.html -->
<!-- filter 过滤器元素将一个名字与一个实现 javax.servlet.Filter接口的类相关联。 -->
<!-- filter是个request到达servlet之前预处理request,也可以在离开servlet时处理response. 是一个”servlet chaining”(servlet 链).一个filter 包括:
1. 在servlet被调用之前截获;2. 在servlet被调用之前检查servlet request;3. 根据需要修改request头和request数据;4. 根据需要修改response头和response数据;
5. 在servlet被调用之后截获. login-filter为本系统定义的一个filter 包com.travelsky.filter.LoginFilter -->
<!-- 多个过滤器 会用FilterChain来决定次序 -->
<!-- <filter-name>子元素定义了—个过滤器的名字,<filter-class>指定了由容器载入的实际类,<init-param>子元素为过滤器提供初始化参数 -->
<!-- 参考 http://www.cnblogs.com/jinzhengquan/archive/2011/02/16/1955778.html -->
<filter>
<filter-name>login-filter</filter-name>
<filter-class>com.travelsky.filter.LoginFilter</filter-class>
</filter>
<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>org.csair.sshframework.app</param-value>
</init-param>
</filter>
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class>
</filter>
<!-- 一旦命名了一个过滤器,就要利用filter- mapping元素把它与一个或多个servlet或JSP页面相关联 -->
<!-- <filter-mapping> 主要由<filter-name>,<servlet-name>和<url-pattem>子元素组成。<servlet-name>将过滤器映射到一个或多个Servlet上,
<url-pattem>将过滤器映射到—个或多个任意特征的URL的JSP页面。 /* 表示 所有的请求都会拦截 -->
<filter-mapping>
<filter-name>login-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- context-param,它用于向 ServletContext 提供键值对,即应用程序上下文信息。我们的 listener, filter 等在初始化时会用到这些上下文中的信息 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:applicationContext.xml
</param-value>
</context-param>
<!--<listener>-->
<!--<listener-class>com.travelsky.listener.StartUpListener</listener-class>-->
<!--</listener>-->
<!--使用ContextLoaderListener监听器。这个监听器中会有一个ContextLoade类用来获取这个context-param 配置文件中的信息contextConfigLocation spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list>
<!-- 在返回特定HTTP状态代码时,或者特定类型的异常被抛 出时,能够制定将要显示的页面。http://blog.csdn.net/ly5156/article/details/6950081 -->
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/error.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.NullException</exception-type>
<location>/error.jsp</location>
</error-page>
</web-app>
2. spring配置文件 applicationContext.xml位置/src/main/resources.
3. accounts.properties 或者 jdbc.properties 位置/src/main/resources
4. freemaker模板
struct 赋值给html页面是这样的,setAttribute(“name”,”wenjiabao”);
页面 <html:text property="name" value="${requestScope.name}"/>
struts 中在struts.xml声明了type类型为freetype表示使用fremake模版。Action使用getxxxxxx(){};将xxxxxx变量形式向fremake模版.ftl赋值。
${…}是模版中的变量,<#--和--> 表示是注释,
Freemaker if…else指令 : 是以 <#指令>开始的标签 以</#指令>结束的标签 <#if animals.python.price < animals.elephant.price> 输出内容1 <#else> 输出内容2 </#if>
freemaker循环指令 :<#list animals as being> <tr><td> ${$being.name}</td></tr> </#list>
freemaker 包含指令include : <#include “../../derectory/test.html”>
freemaker 不允许< <#与指令之间有空格 特殊符号转义使用 / /”双引号 /’单引号
java action处理:freemarker.template.Configuration 创建configuration实例
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates")); //模版存放的目录
cfg.setObjectWrapper(new DefaultObjectWrapper()); //默认
/* 在整个应用的生命周期中,这个工作你可以执行多次 */
/* 获取或创建模板*/
Template temp = cfg.getTemplate("test.ftl");
/* 创建数据模型 */
Map root = new HashMap();
root.put("user", "Big Joe");
Map latest = new HashMap();
root.put("latestProduct", latest);
latest.put("url", "products/greenmouse.html");
latest.put("name", "green mouse");
/* 将模板和数据模型合并 */
Writer out = new OutputStreamWriter(System.out);
temp.process(root, out);
out.flush();
注意:
为了简单起见,这里压制了异常(在方法签名中声明了异常,译者注),而在正式运行的产品中不要这样做。
5. com.opensymphony.xwork.ActionContext(SerletActionContext)
ActionContext是action对象执行的上下文,属于map类型,存放的是Action在执行的需要用到的对象,如:请求的参数(Parameter),会话(Session)、Servlet上下文(ServletContext)、本地化信息(Location)等。
得到请求信息中的Usename如下:
Map session = ActionContext.getContext().getSession();//取得httpSession
ActionContext context = ActionContext.getContext(); //取得当前的ActionContext对象
Map params = context.getParameters();
String username = (String) params.get(“username”);
ServletActionContext对象继承ActionContext,提供了直接与JavaServelet相关对象的访问。可以取得如下对象:
javax.servlet.http.HttpServletRequest:HTTPservlet请求对象
javax.servlet.http.HttpServletResponse;:HTTPservlet相应对象
javax.servlet.ServletContext:Servlet 上下文信息
javax.servlet.ServletConfig:Servlet配置对象
javax.servlet.jsp.PageContext:Http页面上下文
二、 B2bDataserver
6. spring配置文件 applicationContext.xml位置/src/main/resources
7. spring 注入注释使用
@Autowised 它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去.
当@Autowired没有匹配的bean时,会爆出错来的抛出 BeanCreationException 异常。可以@Autowired(required=false)时,就不会抛出上述异常。
当@Autowired匹配多个bean时,也会抛出BeanCreationException 异常。可以使用@qualifier 来指定使用哪个名字(即配置 中的id值)的bean对象。如:
@Autowired
public void setOffice(@Qualifier("office")Office office) {this.office = office;}
@resource 作用与@Autowired 但@Resourse默认通过name注入,而@Autowired通过type注入。
@Resource 有两个属性是比较重要的,分别是 name 和 type,Spring 将 @Resource 注释的 name 属性解析为 Bean 的名字,而 type 属性则解析为 Bean 的类型。所以如果使用 name 属性,则使用 byName 的自动注入策略,而使用 type 属性时则使用 byType 自动注入策略.
@Resourse驱动需要注册bean <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
@Postconstruct 和@Predestroy标签 @Postconstruct 在类初始化后进行调用,@Predestroy是类destroy之前调用。此两个参数是用在方法前标注的。在xml配置中是对应init-method和destroy-method两个方法。
在spring的xml配置文件中<beans>配置 <context:annotation-config/>。 将隐式地向 Spring 容器注册 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及 equiredAnnotationBeanPostProcessor 这 4 个 BeanPostProcessor。
@Component 是对应xml配置中的一个bean配置. 其@SCOPE属性为single 也可以指定@Scope为prototype,这样每次返回的每次实例都是新的
@Scope("prototype")
@Compnent(“boss”) //将bean Boss名称定义为boss
Public class Boss{}
扫描过滤类:
过滤器类型 说明
注释 假如 com.baobaotao.SomeAnnotation 是一个注释类,我们可以将使用该注释的类过滤出来。
类名指定 通过全限定类名进行过滤,如您可以指定将 com.baobaotao.Boss 纳入扫描,而将 com.baobaotao.Car 排除在外。
正则表达式 通过正则表达式定义过滤的类,如下所示: com\.baobaotao\.Default.*
AspectJ 表达式 通过 AspectJ 表达式定义过滤的类,如下所示: com. baobaotao..*Service+
@Servive @Repository @Controller分别对应持久层,业务层,和控制层,作用和@Component等同。
参考:http://www.ibm.com/developerworks/cn/java/j-lo-spring25-ioc/
@SuppressWarnings("unchecked") 屏蔽某些编译时的警告信息,在强制类型转换的时候编译器会给出警告
8. Spring取bean
可以使用 BeanFactory factory = new XmlBeanFactory(resource); factory.getBean(bean名称); 也可以使用 appContext = new ClassPathXmlApplicationContext("springDataservice/applicationContext.xml"); appContext。getBean(bean名称);
9. 线程
线程、线程组、什么是幽灵线程(为其他线程提供服务资源数据的线程)
新线程态,可运行态,非运行态(sleep suspend wait 等待1/o),死亡态
Java中建立线程有两种方法,一种是继承Thread类,另一种是实现Runnable接口。提出采用Runnable接口。
java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
答:有两种实现方法,分别是继承Thread类与实现Runnable接口
用synchronized关键字修饰同步方法
反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
三、 设计模式 (headfirst)
10. 工厂模式
可以利用静态方法定义为简单工厂的方法.也是常见技巧。
用工厂类初始化客户类(如比萨店)。
依赖倒置原则:具体类最好依赖抽象,不要依赖具体类!最好在驱动类中来实例化具体类!
不管是高层组件还是低层组件,依赖抽象是最好的设计原则!
怎么做到上述原则:类中变量不可以持有具体类(即使用new一个对象),使用工厂类实现。
不要让类派生来自具体类。可以不要覆盖基类中已经实现的方法。
抽象工厂模式:使客户类提供接口创建一系列的相关和依赖的对象家族,而不需要指定具体类.
11. 单件模式
定义:确保一个类只有一个实例,并提供一个全局访问点。
Java 使用 static synchronized 来对实例对象的方法进行修饰,不允许多个线程执行此方法,但同步一个方法使性能下降100倍,如果使用volatile 修饰唯一的实例对象时,volatile关键词可以确保:对象被初始化成单列对象时,只有第一次彻底检查对象是否为空执行synchronized 里面的代码 (参见73页)。
volatile定义:如果一个字段被声明成volatile,java线程内存模型确保所有线程看到这个变量的值是一致的。
单件模式确保有一个静态变量和一个静态方法,一个私有构造方法。
12. 命令模式-封装调用
将命令单独做成一个类,将对象与命令解耦合,在测试驱动时再传递一个对象个命令对象来驱动命令的执行,命令类里面装载一个要执行它的对象。命令可以达到多个对象的复用,也易于扩展命令类。
空命令类:初始化使用命令的类的对象,里面的方法皆为空方法。
为了更好的管理命令类对象和使用的类,我们也许还需要一个管理类。
宏命令:一次执行一组命令。将一组命令封装到一个宏命令类里面一起执行。宏命令也需要传入一个执行命令的对象。
命令模式的应用:队列请求,包括:工作队列,线程池,日程安排
工作队列:请求命令类对象不停的往工作队列填充命令类对象,处理命令类的对象的线程在另外一端取出命令,分发给相应处理此命令的线程来执行(excute())。完成后,将命令在队列中删除,然后继续取命令对象,如此循环不停的工作,主线程取出来命令后,分发给相应处理此命令的线程来完成其命令的请求。
Web服务器模式即为此模式架构。
命令模式的定义:将请求封装成对象,这可以让你使用不同的请求,日志,队列来参数化其他对象。
13. 适配器模式
适配器模式类的书写:1。需要先继承要转换成的类型接口,2.将要被转化的类的对象传入本类中。3进行适配。目的是使两个不同的类(对象)通过适配器转化后,可以使用同样的api 实现共同的目标接口,达到同样的使用效果。
定义:将一个类转化成客户期望的类的接口,可以将两个类亲密无间的合作工作。客户只看到目标接口。
Java 系统 enumeration类(不存在remove()方法)适配成iterator类类使用,iterator类中remove 方法声明为unsupportoperationException类型。EnumerariotnIterator适配器中 public void remove( throw new unsupportoperationException(); )
14. 外观模式
定义:将接口变得更简单。封装接口,以一种简单的表现形式展现。
15. 装饰模式
类应该对扩展开放,对修改关闭,通俗设计类时应该允许对其扩展,不要对其进行修改。
16. 观测者模式
定义:定义了一对多的关系,当主题对象发生改变时,观测者对象可以得到更新的消息。也可以取消观察。是定义了一系列对象的一对多的关系。
在观测者中引用主题来注册或反注册观测者自身,在主题对象中引用来观测者的方法把数据传给观测者对象。
17. 模版方法模式—封装算法
模版的基类一般是一个抽象类,其实是一个算法模版,定义了算法的步骤,可以起到规范算法的作用,但同时又把一些步骤放到子类中去实现的,把公用的方法放里面,不共用的方法声明空方法,继承类各自实现空的方法,来实现做到自己的业务
钩子方法:是模版类中的空方法,由子类继承来实现的方法,也由子类决定是否实现,一般是实方法,钩子的作用也可以作为类中的条件控制语句。
模版模式中方法:钩子方法,抽象方法,一般其他方法,若子类必须实现的方法,使用抽象方法,可以实现也可以不用实现的话,则可以钩子方法。
好莱坞原则:别调用我们(别打电话给我们),我们会调用你的(高层组件对待低层组件的原则)。
Java例子:Java 数组使用了模版类钩子实现,sort()中方法merger()方法调用钩子compareTo()来的。compareTo()来自接口conparable接口,故需要排序的类需要继承comparable接口并且在类中compareTo()方法,此方法是实现两个对象的比较,返回两个对象的大于,等于或者小于。
Java例子 jframe:swing容器,jframe是最基本的swing的容器,中有paint()方法,是一个钩子方法,什么事情都不做,覆盖paint()方法画出你需要的图形。
Java例子:applet程序,此程序也是使用钩子的,其钩子函数们为:init(),stop(),destroy(),paint(),start();
18. 迭代器和组合模式
书本例子(221):菜单类使用array 菜单类2使用arrayList 类型:统一起来使用iterator,写一个iterartor类来继承接口iterator,然后传入数组,将数组实现hasNext(),和next()方法.(,同样也需要将arrayLIst也如前一个一样实现一个iterator.)在array数组类添加此类的对象函数创建一个iterator对象,然后在客户端waitress类里面调用菜单类的createrIterator来创建一个itrator对象就可以统一的使用。实际上添加了两个迭代器,然后在原来的类里面添加两个转化成迭代器的方法,就可以统一的使用!
使用java的系统接口iterator来改良上述的设计(java.util.iterator),把创造迭代器放在menu接口,让原来的两个菜单来继承现在的菜单接口,在waitress类中就可以使用统一的menu接口声明原来的两个菜单类,好处是使waitress类针对接口编程,不再是针对实现编程。
定义:提供一种统一的方法顺序方法聚合元素内的各个对象,但又不会暴露聚合类内的内部表示
这样代码更容易维护,也易于扩展。
设计原则:一个类应该只有一个引起变化的原因.如管理聚合类,和遍历聚合类就为两个变化的原因。其中一个变化整个类也变化,因此最好将其中一个变化的原因的责任分配给另一个新的类来处理!减少了耦合。
19. 组合模式---承迭代模式
定义:允许你将对象组合成树形结构来表现“整体/部分”层次结构,组合可以让客户以一致的方式来处理个别对象和对象组合。
承上7)上列菜单例子解说,现在菜单需求为:已经是一个树形菜单。设计变更为:设计一个menuComponent抽象类,拥有子菜单和菜单节点的方法和属性并且还有一个创造迭代器接口的方法,其方法初始化都为抛出异常 void ….{throw new UnsupportOprationException ;};其子菜单类和菜单节点类都继承上述的类,将相应的方法实现,遍历时可以使用之前的创建迭代器的接口,
下面是菜单的遍历的代码:
public void print() {
System.out.print("\n" + getName());
System.out.println(", " + getDescription());
System.out.println("---------------------");
Iterator iterator = menuComponents.iterator();
//本段代码需要结合下面的CompositeIterator类来看
while (iterator.hasNext()) {
MenuComponent menuComponent =
(MenuComponent)iterator.next();
menuComponent.print();
}
}
下面是实现了遍历的树的菜单的迭代器类。
package headfirst.composite.menuiterator;
import java.util.*;
public class CompositeIterator implements Iterator {
Stack stack = new Stack();
public CompositeIterator(Iterator iterator) {
stack.push(iterator);
}
public Object next() {
if (hasNext()) {
Iterator iterator = (Iterator) stack.peek();
MenuComponent component = (MenuComponent) iterator.next();
if (component instanceof Menu) {
stack.push(component.createIterator());
}
return component;
} else {
return null;
}
}
public boolean hasNext() {
if (stack.empty()) {
return false;
} else {
Iterator iterator = (Iterator) stack.peek();
if (!iterator.hasNext()) {
stack.pop();
return hasNext();
} else {
return true;
}
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
空迭代器:菜单内没有任何可以迭代的数据;package headfirst.composite.menuiterator;
import java.util.Iterator;
public class NullIterator implements Iterator {
public Object next() {
return null;
}
public boolean hasNext() {
return false;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
20. 状态模式—状态机
四、 Java知识
1. Map遍历
GfMetaData metaData = new GfMetaData();
Iterator iter = TKTDataContextListener.gfTktDataFields.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
companyCode = entry.getKey().toString();
metaData = (GfMetaData) entry.getValue();
}
Iterator item = TKTDataContextListener.gfTktDataFields.keySet().iterator();
while (item.hasNext()) {
companyCode = item.next().toString();
metaData = (GfMetaData) map.get(companyCode);
}
2. Maven 编译命令
先进入工程,然后 cmd,输入命令 maven clean install –Dmaven.test.skin=true 编译以后将在target下找到包。
3. Marshaller
将一个对象转换成xml
4. Java.util.properties
Properties是一个以”key=value”值来存储值的类。
java.lang.Object java.util.Dictionary<K,V> java.util.Hashtable<Object,Object> java.util.Properties
主要方法有 load(Properties输入流对象),keySets(); get(key值)
作用主要是用来对常见的properties类型的文件处理
五、 Mule学习
1. muleIDE安装
Eclipse 3.5/3.6/3.7 (Galileo/Helios/Indigo) 按以下步骤安装Mule IDE:
1. 进入eclipse,点击菜单Help > Install New Software.
2. 点击Add 按钮,弹出的的对话框,在Location中输入 http://dist.muleforge.org/mule-ide/updates-2.1.x/ 后按Enter。Mule IDE就会出现在可用软件列表里。
3. 选中Mule IDE后点击Next. Eclipse将会运行一会,完成后点击Next。
4. 浏览Mule IDE license, 选择accept the license, 然后点击Finish。
5. 点击Yes重启Eclipse.
2. Esb简介
功能:在服务与服务之间路由消息,在请求者与服务者之间转换协议或转换协议格式,处理来自异构的事物。
3. Mule管理
4. Mule消息流程
Appliction channel => MessageReceive|Connect|Transformer =>InboundRounter => interpter|lifecycle Adapt =>
UMO Componet=>
Outbound Rounter=> MessageReceive|Connect|Transformer => interpter|lifecycle Adapt => Appliction channel
5. Mule服务器端
端点endpoint,使用什么协议。
UMO compont
Mule管理器
Mule服务器通知 Mule事件 Mule事务
6. Mule客户端
第三条包括对数据库的配置和支持。
MuleClient muleClient = new MuleClient(muleContext);
//Create client for existing Mule instance context
String actualHash =
muleClient.send("vm://Md5FileHasher.In",tempFileName, null).getPayload();//Use client to perform synchronous send to endpoint
assertEquals(expectedHash, actualHash);
实例2:
MuleClient muleClient = new MuleClient(false);//Creates empty Mule instance and client connected to it
MuleMessage response =muleClient.send(
"http://www.google.com/finance/historical?q=NASDAQ:GOOG&histperiod=weekly&output=csv",null, null);// Performs synchronous send
using HTTP transport
String payload = response.getPayloadAsString();//Retrieves result of
HTTP call as string
muleClient.dispose();//Disposes client
实例3
MuleClient muleClient =new MuleClient("conf/raw-jms-muleclient-config.xml"); // Creates client and configures MuleStarts theMule instance
muleClient.getMuleContext().start(); //Performs synchronousread using JMStransport
// Disposes configured Mule instance, then client
MuleMessage response = muleClient.request("jms://"+ queueName+ "?connector=amqConnector", 1000);
muleClient.getMuleContext().dispose();
muleClient.dispose();
7. Mulecontext api
Controlling a Mule instance: muleContext.start();muleContext.dispose();
Reading the configuration
Accessing statistics
Looking up the registry
Service service = muleContext.getRegistry().lookupService(serviceName);
service.getStatistics().logSummary(new XMLPrinter(xmlStatisticsWriter));
8. MuleEvent contaxt api
Prospecting messages
A Mule message object contains properties and a payload, and optionally an exception, some attachments, and cached values.
Influencing message processing
9. Transformer
Transformers can be chained to cumulate their effects.:
Byte[]=>XSL-T transformer=> Byte[]=>object to string transformer =>String => object To JMs message=>JMs text meessage
10. Router
=> filer + Endpoint =>
filer + Endpoint ROUNT =>
filer + Endpoint=>
一个实例的流程:
=>Inbound endpoint HTTP port => Inbound router => XSL transformer(Byte[] to BYTe[] )=> component => outbound pass-through route=>outbound endpoint JMS destination=>
11. Mule Action
参考文章http://my.oschina.net/moon/blog/40125
六、 Skybus
AbstractTransformer doTransform()方法是抽象类。
notifications 元素: These notifications are generated when specific events occur inside Mule, such as when an instance starts or stops, when an exception has been caught, or when a message is received or dispatched.5