简体   繁体   English

如何在 Spring 的 @Transactional 中使用 @Resource WebServiceContext 注入

[英]How to use @Resource WebServiceContext injection with Spring's @Transactional

I hava a Metro jax-ws webservice that looks more or less like this:我有一个 Metro jax-ws 网络服务,看起来或多或少像这样:

@WebService
@Transactional
public class UserManagementServiceImpl {

    @Resource
    private WebServiceContext context;

    ...
}

The WebServiceContext is allways null. WebServiceContext总是 null。 However, if I remove @Transactional the WebServiceContext is injected.但是,如果我删除@Transactional ,则会注入 WebServiceContext。

Anybody knows a workaround?有人知道解决方法吗?

Thanks.谢谢。

I've found a workaround.我找到了解决方法。 Use setter injection instead of field injection:使用 setter 注入代替字段注入:

@WebService
@Transactional
public class UserManagementServiceImpl {

    private WebServiceContext context;

    @Resource
    public void setContext(WebServiceContext context) {
        this.context = context;
    }
    ...
}

The problem with webservices and the transaction management is that each creates a proxy of the class, and the 2nd one to create a proxy doesn't get the real implementation but the proxy (and things go south). Web 服务和事务管理的问题在于,每个都创建了 class 的代理,而第二个创建代理并没有得到真正的实现,而是代理(以及 go 南部的东西)。

The way to avoid this is to delegate all the calls from the webservice endpoint implementation to the service.避免这种情况的方法是将 Web 服务端点实现的所有调用委托给服务。 So you'll need two concrete classes:S.所以你需要两个具体的类:S。

I don't know if this is the best way to do it, but it's the best I've found.我不知道这是否是最好的方法,但这是我发现的最好的方法。

And it might clean up the code a bit, as it looks like the User Manager cares about webservices, which doesn't look right.而且它可能会稍微清理一下代码,因为看起来用户管理器关心 web 服务,这看起来不正确。

I suspect this may cause problems when handling simultaneous calls to the web service since the Servlet is a singleton, all instance data is "shared" by all threads - so your "private context" will keep being overridden by the next call even while you are still busy with a previous call.我怀疑在处理对 web 服务的同时调用时这可能会导致问题,因为 Servlet 是 singleton,所有实例数据都由所有线程“共享” - 所以即使你在仍然忙于上一个电话。 Maybe something like也许像

ThreadLocal<WebServiceContext> WSS = new ThreadLocal<WebServiceContext>();

@Resource
public void setContext(WebServiceContext context) {
    WSS.set(context);
}

// then where you need the context use WSS.get();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM