cxf 请求作用域 bean 在单元测试中不起作用(soap)
cxf request scoped bean not working in unit test (soap)
CXF soap 应用程序,使用以下版本:
springBootVersion = 1.2.3.RELEASE
springVersion = '4.1.6.RELEASE'
cxfVersion = '3.1.0'
junitVersion = '4.12'
我有一个请求范围为 spring 的 bean:
@Component
@Scope( value=WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS )
public class RequestScopedClass
我在 CXF 端点实现中从 ApplicationContext 动态获取:
@Component
@WebService(endpointInterface = "ch.xyz.PaymentServiceInterface" )
public class PaymentServiceImpl implements PaymentServiceInterface
{
...
RequestScopedClass rsc = appCtxt.getBean( RequestScopedClass.class );
rsc.doSomething();
我的目标是通过模拟连接到侦听器端口等的客户端来测试 soap 服务的前端,确保执行带有拦截器链(包括我的自定义拦截器)的整个 cxf 堆栈。我设法通过包含
来设置此配置
org.apache.cxf:cxf-rt-transports-http-jetty
依赖并在测试设置中启动端点:
String address = "http://0.0.0.0:8080/";
myEndpoint = Endpoint.publish( address, new PaymentServiceImpl() );
运行 测试在调用 rsc.doSomething():
时抛出 BeanCreationException
Error creating bean with name 'scopedTarget.requestScopedEnvironment': Scope 'request' is not active ...
如果我将 proxyMode 更改为其他三种可能性之一,则在从 appCtxt 获取 bean 时已抛出相同的异常。
测试由
注释
@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( classes = {
...,
RequestScopedClass.class
}
)
@WebAppConfiguration
如果应用程序由 "gradle bootrun" 在命令行上启动并且 soap 请求由 chrome postman 应用程序完成,一切都很好,我得到了预期的 soap 响应。
在单元测试中执行 cxf soap 服务器时,我该怎么做才能使请求范围有效?
同时我找到了解决方案:
...
import org.springframework.context.ConfigurableApplicationContext;
@Autowired
private ConfigurableApplicationContext myCtxt;
@Before
public void setUp() throws Throwable
{
myCtxt.getBeanFactory().registerScope( "session", new CustomScope4Test() );
myCtxt.getBeanFactory().registerScope( "request", new CustomScope4Test() );
}
public class CustomScope4Test implements Scope
{
private final Map<String, Object> beanMap = new HashMap<String, Object>();
/**
* @see org.springframework.beans.factory.config.Scope#get(java.lang.String, org.springframework.beans.factory.ObjectFactory)
*/
public Object get( String name, ObjectFactory<?> factory )
{
Object bean = beanMap.get( name );
if ( null == bean )
{
bean = factory.getObject();
beanMap.put( name, bean );
}
return bean;
}
/**
* @see org.springframework.beans.factory.config.Scope#getConversationId()
*/
public String getConversationId()
{
// not needed
return null;
}
/**
* @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(java.lang.String, java.lang.Runnable)
*/
public void registerDestructionCallback( String arg0, Runnable arg1 )
{
// not needed
}
/**
* @see org.springframework.beans.factory.config.Scope#remove(java.lang.String)
*/
public Object remove( String obj )
{
return beanMap.remove( obj );
}
/**
* @see org.springframework.beans.factory.config.Scope#resolveContextualObject(java.lang.String)
*/
public Object resolveContextualObject( String arg0 )
{
// not needed
return null;
}
}
CXF soap 应用程序,使用以下版本:
springBootVersion = 1.2.3.RELEASE
springVersion = '4.1.6.RELEASE'
cxfVersion = '3.1.0'
junitVersion = '4.12'
我有一个请求范围为 spring 的 bean:
@Component
@Scope( value=WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS )
public class RequestScopedClass
我在 CXF 端点实现中从 ApplicationContext 动态获取:
@Component
@WebService(endpointInterface = "ch.xyz.PaymentServiceInterface" )
public class PaymentServiceImpl implements PaymentServiceInterface
{
...
RequestScopedClass rsc = appCtxt.getBean( RequestScopedClass.class );
rsc.doSomething();
我的目标是通过模拟连接到侦听器端口等的客户端来测试 soap 服务的前端,确保执行带有拦截器链(包括我的自定义拦截器)的整个 cxf 堆栈。我设法通过包含
来设置此配置org.apache.cxf:cxf-rt-transports-http-jetty
依赖并在测试设置中启动端点:
String address = "http://0.0.0.0:8080/";
myEndpoint = Endpoint.publish( address, new PaymentServiceImpl() );
运行 测试在调用 rsc.doSomething():
时抛出 BeanCreationExceptionError creating bean with name 'scopedTarget.requestScopedEnvironment': Scope 'request' is not active ...
如果我将 proxyMode 更改为其他三种可能性之一,则在从 appCtxt 获取 bean 时已抛出相同的异常。
测试由
注释@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( classes = {
...,
RequestScopedClass.class
}
)
@WebAppConfiguration
如果应用程序由 "gradle bootrun" 在命令行上启动并且 soap 请求由 chrome postman 应用程序完成,一切都很好,我得到了预期的 soap 响应。
在单元测试中执行 cxf soap 服务器时,我该怎么做才能使请求范围有效?
同时我找到了解决方案:
...
import org.springframework.context.ConfigurableApplicationContext;
@Autowired
private ConfigurableApplicationContext myCtxt;
@Before
public void setUp() throws Throwable
{
myCtxt.getBeanFactory().registerScope( "session", new CustomScope4Test() );
myCtxt.getBeanFactory().registerScope( "request", new CustomScope4Test() );
}
public class CustomScope4Test implements Scope
{
private final Map<String, Object> beanMap = new HashMap<String, Object>();
/**
* @see org.springframework.beans.factory.config.Scope#get(java.lang.String, org.springframework.beans.factory.ObjectFactory)
*/
public Object get( String name, ObjectFactory<?> factory )
{
Object bean = beanMap.get( name );
if ( null == bean )
{
bean = factory.getObject();
beanMap.put( name, bean );
}
return bean;
}
/**
* @see org.springframework.beans.factory.config.Scope#getConversationId()
*/
public String getConversationId()
{
// not needed
return null;
}
/**
* @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(java.lang.String, java.lang.Runnable)
*/
public void registerDestructionCallback( String arg0, Runnable arg1 )
{
// not needed
}
/**
* @see org.springframework.beans.factory.config.Scope#remove(java.lang.String)
*/
public Object remove( String obj )
{
return beanMap.remove( obj );
}
/**
* @see org.springframework.beans.factory.config.Scope#resolveContextualObject(java.lang.String)
*/
public Object resolveContextualObject( String arg0 )
{
// not needed
return null;
}
}