2011-04-28 15 views
6

de Primavera I HAVA un servicio web JAX-WS metro que se ve más o menos así:Cómo utilizar la inyección @Resource WebServiceContext con @Transactional

@WebService 
@Transactional 
public class UserManagementServiceImpl { 

    @Resource 
    private WebServiceContext context; 

    ... 
} 

El WebServiceContext siempre se encuentra nula. Sin embargo, si elimino @Transactional, se inyecta WebServiceContext.

¿Alguien sabe una solución?

Gracias.

+0

¿La clase está implementando alguna interfaz? En ese caso, puede tener algo que ver con el problema explicado en esta pregunta: http://stackoverflow.com/questions/2713033/autowire-strange-problem – Javi

Respuesta

4

He encontrado una solución. Utilizar la inyección de setter en lugar de la inyección campo:

@WebService 
@Transactional 
public class UserManagementServiceImpl { 

    private WebServiceContext context; 

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

El problema con los servicios web y la gestión de transacciones es que cada uno crea un proxy de la clase, y el segundo para crear un proxy no obtiene la implementación real sino el proxy (y las cosas van al sur).

La forma de evitar esto es delegar todas las llamadas desde la implementación del punto final del servicio web al servicio. Entonces necesitarás dos clases concretas: S.

No sé si esta es la mejor manera de hacerlo, pero es lo mejor que he encontrado.

Y puede limpiar el código un poco, ya que parece que el Administrador de usuarios se preocupa por los servicios web, que no se ve bien.

1

Sospecho que esto puede causar problemas al manejar llamadas simultáneas al servicio web desde el servlet es un producto único, todos los datos de instancia es "compartida" por todos los temas - por lo que su " contexto privado "seguirá siendo anulado por la próxima llamada, incluso mientras está ocupado con una llamada anterior. Tal vez algo así como

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

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

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