??xml version="1.0" encoding="utf-8" standalone="yes"?> Figure 1 Test Code Structure Each test implementation could be divided into four layers, this structure could help us improve the codes reusability and maintainability, So, it will make us implement the tests quickly and easily. Specification/Scenario layer: This layer describes system’s behaviors and functionalities by the scenarios. For using JBehave, we can use the natural language describe the scenarios and just need to follow the JBehave ‘Given-When-Then’ rule. Parser layer: We don’t need to implement this layer , this layer has been implemented by JBehave. What exactly JBehave do is to relate the steps of the scenario to the methods of the test codes. Step Logic Layer: The layer implements test logics associating with every step of the scenarios. Every step are implemented by a Java method. Action/Utils layer This the very important layer to improve the reusability of our codes. This layer provides the utility methods to help you implement step logics. These utility methods usually involved the system state checking, mock requests sending and so on. For example, we can provide the methods to check the data in database/file or check the state of the middleware, also so frameworks are very useful to implement the logic simulating the client browser’s requests. Working for Amazon.com chaocai2001@yahoo.com.cn
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface NeedToRetry {
Class<?>[] recoverableExceptions();
int retryTime();
int intervalIncrementalFactor() default 0;
long retryInterval() default 0L;
}
2 The Aspect
@Aspect
public class InvokingRetryInterceptor {
private static Logger log = Logger.getLogger(InvokingRetryInterceptor.class);
private boolean isNeedToRetry(Throwable t,Class<?>[] recoverableExceptions){
String exceptionName= t.getClass().getName();
for (Class<?> exp:recoverableExceptions){
if (exp.isInstance(t)){
return true;
}
}
log.warn("The exception doesn't need recover!"+exceptionName);
return false;
}
private long getRetryInterval(int tryTimes,long interval,int incrementalFactor){
return interval+(tryTimes*incrementalFactor);
}
@Around(value="@annotation(amazon.internal.dropship.common.NeedToRetry)&&@annotation(retryParam)",argNames="retryParam")
public Object process(ProceedingJoinPoint pjp,NeedToRetry retryParam ) throws Throwable{
boolean isNeedTry=true;
int count=0;
Throwable fault;
Class<?>[] recoverableExceptions=retryParam.recoverableExceptions();
int retryTime=retryParam.retryTime();
long retryInterval=retryParam.retryInterval();
int incrementalFactor=retryParam.intervalIncrementalFactor();
do{
try{
return pjp.proceed();
}catch(Throwable t){
fault=t;
if (!isNeedToRetry(t,recoverableExceptions)){
break;
}
Thread.sleep(getRetryInterval(retryTime,retryInterval,incrementalFactor));
}
count++;
}while(count<(retryTime+1));
throw fault;
}
}
]]>
The followings will introduce how to use the JBehave in your real project effectively.
Chao Cai
]]>
1 ?/span>EAR形式部v
?/span>CXF的应用以WAR的Ş式包含在EAR中,?/span>EAR?/span>META-INF中的配置文gapplication.xml中声明你?/span>WARQƈ?/span>weblogic-application.xml中加入以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90">
<application-param>
<param-name>webapp.encoding.default</param-name>
<param-value>UTF-8</param-value>
</application-param>
<prefer-application-packages>
<package-name>javax.jws.*</package-name>
</prefer-application-packages>
</weblogic-application>
q个配置是告诉应用服务器的类装蝲器对于该EAR而言优先使用?/span>EAR?/span>javax.jws.*的实现?/span>
2 在应用服务器启动时加?/span>Java VM参数
-Djavax.xml.soap.MessageFactory=com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
好了现在一切搞定!
(蔡超 chaocai2001@yahoo.com.cn)
SRP(Single Responsible Principle), 单一职责原则Q这是面对的最基本原则Q也是实现弹性设计的最基本原则?/font>
每个cL接口定义应该只包含一U明的职责Q同时仅有一U原因会Dq种定义的修攏V一个复杂的cL接口的定义包含多个责任,很容易你的设计失去Ҏ,很多因素都会Dq个cL接口的变_׃它含有多U职责,q就意味着它是多种服务的提供者,会有多种依赖于它的客LQ他的变更可能会D大范围的变更?/span>
在作者看来,优先U最高的是你首先要保证接口的单一职责及方法的单一职责Q接口通常意味可以更换不同的实玎ͼZ个接口定义过多的职责意味着每个实现都会涉及多个职责Q这导致无法实现更粒度的实现的复用?/span>
2 面向抽象~成
如果你已l读q?font face="Times New Roman">GOF的《设计模式》,你便知道其中每一个模式都是基于此原则的,抽象Q或接口Q有效的解除了服务调用者和服务提供者间的耦合?/font>
3 使用配置
通过修改配置文g便可以改变系l的某些Ҏ,q种修改的区别于修改代码Q对?font face="Times New Roman">Java,C++而言q种修改是不需要编译,有的修改甚至可以在运行时生效?/font>DSL地运用可以配置更加h可读性及更强的描q能力。在设计时将实现分ؓ配置及框枉分是非常灉|的结构?/font>
蔡超
HP 软g架构?br />
软g架构N
SCEA
IBM Certified Solution Designer for OOA&D vUML2
Chaocai2001@yahoo.com.cn
下蝲教程和示?
http://www.tkk7.com/Files/chaocai/spring-osgi.rar
http://www.tkk7.com/Files/chaocai/mini-container-beta-0.9-a.rar
源码下蝲没有问题可以l箋下蝲?br />
首先我们分析OSGi的特点及可以l我们应用带来的好处
1 良好的动态特?/span>
2 更细_度的类装蝲控制Q多个版本组件在同一q行环境中共同运?/span>
3 ?/span>JVM内部实现SOAQ我个h倒是认ؓOSGi所涉及的仅仅是SOA思想的一部分)
4 DS提供?/span>IoC支持
h考你的应用程序真的需要这些吗Q?/span>
很多设计和开发h员都会在设计和实现时忽略应用的真正需要和OSGi的复杂性,应用的所有内部细划分都采用Bundle实现?/span>
而我们除了应该注意采?/span>OSGi开发和调试带来的复杂性;同时也要明白动态特性的支持q不是仅仅采?/span>OSGiq_可以搞定的Q要真正实现动态特性必L意模块的启动序无关性及对其所依赖服务的监听等Q这些都会大大增加系l实现和调试的复杂性?/span>
其实我们应该认真分析应用是否需要这?/span>OSGi的特性及q些Ҏ应该在应用的那些部分体玎ͼ例如我们可以在扩展方面采?/span>Bundle实现扩展插gQ至于其它部分则不必采用q多?/span>BundlesQ甚臛_以采用一个大?/span>BundleQ而其内部则可以采用如Spring来帮助我们实现模块化Q?/span>
同时Q不要忘记其他的framework同样提供了很好的lg化的基础架构?/span>SpringQ?/span>Pico-ContainerQ在OSGi与其它技术合时SCA同样是很好的选择?/span>
保持应用的简单性,不要针对特定技术进行设计,而要计选择适合的技术?/span>
蔡超
Chaocai2001@yahoo.com.cn
下蝲教程和示?
http://www.tkk7.com/Files/chaocai/spring-osgi.rar
蔡超
JEE咨询N
SCEA(1.2&5)
IBM Certified OOA&D Solution Designer vUML2
因此大家在设计过E中不要仅仅分层结构留于Ş式,而要时刻注意设计是否W合q种架构模式Q这h能真正发挥这U架构模式的优势?/span>
getObject() Return an instance (possibly shared or independent) of the object managed by this factory. | |
getObjectType() Return the type of object that this FactoryBean creates, or null if not known in advance. | |
boolean |
()
Q在所有属性注入完成后spring会调用这个方法,因此上面的程序ƈ没有完全正确的模拟spring的调用过E?/span>
修改代码Q?/span>
q次l于成功了!
最后,此例告诉大家有时我们可以直接调用spring中的工具c,来完成我们的Ҏ需求,此时要注意的是正模?/span>spring的对bean创徏和调用过E?/span>
SWF是一U嵌入式的工作流引擎Q它不需要Q何应用服务器的支持?/span>SWF使用十分单,但却可以满多数程驱动应用的需求。ƈ且支持和Lj2ee框架整合(spring).
本文介绍如何ZSWF开发流E驱动的应用?/span>
SWF是一U嵌入式的工作流引擎Q它不需要Q何应用服务器的支持?/span>SWF使用十分单,但却可以满多数程驱动应用的需求?/span>
本文介绍如何ZSWF开发流E驱动的应用?/span>
Spring?/span>XFire可以通过多种方式l合Q下文介l的是笔者常用的一U简单而实用的Ҏ。所用的Spring版本?/span>2.0,XFire版本?/span>1.2.6?/span>
1 配置XFire Servlet
?/span>web.xml中加入如下配|:
<servlet>
<servlet-name>XFireServlet</servlet-name>
<servlet-class>
org.codehaus.xfire.spring.XFireSpringServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/servlet/XFireServlet/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
2 配置Spring的监听器Q同Zspring?/span>Web目一?/span>Spring的监听器是必不可的?/span>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:org/codehaus/xfire/spring/xfire.xml,
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
以下是完整的web.xml配置文g
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:org/codehaus/xfire/spring/xfire.xml,
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>XFireServlet</servlet-name>
<servlet-class>
org.codehaus.xfire.spring.XFireSpringServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/servlet/XFireServlet/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
3 定义接口及实现服?/span>
定义接口Q这个接口中定义要通过WebService暴露的方?/span>
package org.ccsoft;
publicinterface HelloWS {
public String sayHello(String sb);
}
实现服务
package org.ccsoft;
publicclass HelloWSImp implements HelloWS {
public String sayHello(String sb) {
// TODO Auto-generated method stub
return"Hello "+sb;
}
}
4 配置服务
上文中实现的服务,加入?/span>spring的配|文件中?/span>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="helloWS" class="org.ccsoft.HelloWSImp"/>
<bean name="helloService" class="org.codehaus.xfire.spring.ServiceBean">
<property name="serviceBean" ref="helloWS"/>
<property name="serviceClass" value="org.ccsoft.HelloWS"/>
<property name="inHandlers">
<list>
<ref bean="addressingHandler"/>
</list>
</property>
</bean>
<bean id="addressingHandler" class="org.codehaus.xfire.addressing.AddressingInHandler"/>
</beans>
好了现在你可以通过http://127.0.0.1:8080/XFireWS1/services/HelloWS?wsdl来验证是否部|成功了?/span>
————————————————————————————————————?/span>
?/span> ?/span>
SCEA Q?/span> SCBCD Q?/span> MCSD
IBM Certified Specialist RUP
IBM Certified Solution Designer OOA&D UML v2
北京天融信Y件架构师
SUN,Microsoft培训中心牚w高端教师
常年提供架构咨询服务
chaocai2001@yahoo.com.cn Q?/span> 010-82776427
spring 中的 POJO 的生命周期可以是 Singlton 或每h创徏Q或?/span> 2.0 支持?/span> session ?/span> application,request {范_Q?/span> SLSB 是通过实例池经心管理的。如?/span> spring POJO 不采?/span> singlton 的Ş式那么就需要承受创建和销?/span> POJO 的消耗,当然 SLSB 的出池和入池同样会有同步的消耗,׃现在的虚拟机对象的创建和消耗速度大幅提高所以不一定比 SLSB 获取的速度慢,但是如果每个对象构徏的资源消耗很大如L需要构建或初始化复杂对象,那么 SLSB 的速度昄有优ѝ如?/span> spring 采用 singleton 模式Q那么其中如果需要同步,则虽然省M创徏和销毁的消耗,但是大量的同步会使性能的杀手。ƈ且在?/span> CPU 的服务器上没有同步的多线Eƈ行效果更好(可以在不同的处理器上单独q行Q?/span>
2 EJB3 规范要求在部|?/span> EJB 时必ȝ定到各业务接口的全限定名上,最l可?/span> JNDI 查找
如: ctx.lookup(TaxRate.class.getName());
3 @Remove 表示 SFSB 中的删除ҎQ如果存?/span> @PreDestory 则在其后执行
4 会话 Bean 不实?/span> SessionBean 接口Q?/span> MDB 不必实现 MessageDerivenBean Q只要通过 @Annotation 标明或在部v文g中说明?/span>
5 EJBContext 中加入了 lookup ҎQ用于查扑֒ Bean l带?/span> JNDI ?/span>
Q?/span>
SCEA
Q?/span>
MCSD
Q?/span>
IBM RUP Specialist
Q?/span>
Spring Reference 中介l如何在采用 @AspectJ 方式在剖面中如何获取 target ?/span> JoinPoint q给ZCZQ但q没有给出采?/span> XML 配置方式时介l及CZQ下面附上一个简单的例子供大家参考?/span>
package aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* @author Administrator
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class LogAdvice1 {
public void log(JoinPoint jp,MathImp imp){
System.out.println("log:"+imp+" "+jp.toLongString());
}
}
/*
* Created on
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package aop;
/**
* @author Administrator
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class MathImp /*implements Math*/{
/* (non-Javadoc)
* @see aop.Math#add(int, int)
*/
public void add(int op1, int op2) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see aop.Math#addtest(int, int)
*/
public void addtest(int op1, int op2) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see aop.Math#sub(int, int)
*/
public void sub(int op1, int op2) {
// TODO Auto-generated method stub
}
}
配置Q?/span>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- this is the object that will be proxied by Spring's AOP infrastructure -->
<bean id="mathImp" class="aop.MathImp"/>
<!-- this is the actual advice itself -->
<bean id="logger" class="aop.LogAdvice1"/>
<aop:config>
<aop:aspect ref="logger">
<aop:pointcut id="addLog"
expression="execution(* aop.MathImp.*(..)) and target(imp) and JoinPoint(jp)" />
<aop:before pointcut-ref="addLog"
method="log" arg-names="jp,imp" />
</aop:aspect>
</aop:config>
</beans>
试
package aop;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
* @author Administrator
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class Test {
public static void main(String[] args) {
AbstractApplicationContext context=new FileSystemXmlApplicationContext("aop2.xml");
//Math math=(Math) context.getBean("math");
MathImp math=(MathImp) context.getBean("mathImp");
math.add(1,2);
math.addtest(3,4);
math.sub(5,6);
}
}
2 ServiceLocator模式
׃EJB3中省MHome接口Q所以如果用ServiceLocator模式会出现异常,同一JNDI每次获得都会是同一对象即便是有状态的Bean
3 Stateful Session Bean
׃EJB3中省MHome接口QJNDI lookupq回的是一个Session Bean的对象,而不是HomeQ所以EJB3的Spec中规定每ơJNDI lookup
都应该返回一个新的实例。(注意以上q点在一些版本的JBOSS EJB3的实C都存在BUGQ?br />