Weblogic平台,Spring的@Autowired对JAX-WS失效
问题描述:
1. web service类继承了SpringBeanAutowiringSupport, 有一个属性使用了@Autowired
2. 该属性在Tomcat平台能由Spring正确注入, 在weblogic上不能正确注入,导致程序一直抛NullPointerException错误
问题发现的软件版本:
1. Spring 3.0.1
2. Weblogic 10.3
在网上查了很多资料,也看了一些JAX-WS与Spring集成的要点,发现我们的程序写法和配置没有任何问题。
1. WS服务类要继承SpringBeanAutowiringSupport后才能使用@Autowired。
2. web.xml中对ContextLoaderListener的声明一定要在WSServletContextListener的前面。
Java代码:
1 @WebService(name="loginWebService")
2 @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
3 public class LoginWebSvc extends SpringBeanAutowiringSupport{
4
5 @Autowired
6 private ILDAPDao ldapDao;
7
8 /**
9 * @param username
10 * @param password
11 * @return boolean
12 */
13 @WebMethod(operationName = "authenticate")
14 public boolean authenticate(@WebParam(name = "userName") String username,
15 @WebParam(name = "password") String password) {
16 boolean authSuccess = false;
17 try {
18 authSuccess = ldapDao.authenticate(username, password);
19 } catch (Exception e) {
20 log.error(e.getMessage(), e);
21 }
22 return authSuccess;
23 }
24 }
如下是web.xml的片段:
1 <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
2 .....
3 <listener> <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> </listener>
后来在spring的官方网站上看到,这可能是Spring的一个bug,我们临时的解决办法是不使用 @Autowired,而是在使用的时候调用如下的类来创建 ldapDao。
1 import org.springframework.beans.BeansException;
2 import org.springframework.beans.factory.annotation.Autowired;
3 import org.springframework.context.ApplicationContext;
4 import org.springframework.context.ApplicationContextAware;
5
6 public class SpringUtil implements ApplicationContextAware {
7
8 @Autowired
9 private static ApplicationContext applicationContext;
10
11 public void setApplicationContext(ApplicationContext applicationContext)
12 throws BeansException {
13 this.applicationContext = applicationContext;
14
15 }
16
17 public static Object getBean(String beanName) {
18 return applicationContext.getBean(beanName);
19 }
20 }
1 @WebMethod(operationName = "authenticate")
2 public boolean authenticate(@WebParam(name = "userName") String username,
3 @WebParam(name = "password") String password) {
4 ILDAPDao ldapDao = (ILDAPDao)SpringUtil.getBean("ldapDao");
5 boolean authSuccess = false;
6 try {
7 authSuccess = ldapDao.authenticate(username, password)
8 ;
9 } catch (Exception e) {
10 log.error(e.getMessage(), e);
11 }
12 return authSuccess;
13 }
注意:这里不要添加 ldapDao的access method,如果一旦添加,这些方法就需要暴露出来。比如如果在上面的类中加上:
1 @Autowired
2 private ILDAPDao ldapDao;
3
4 public ILDAPDao getLdapDao() {
5 return ldapDao;
6 }
在代码运行过程中会报如下的错误:
1 Caused by: java.security.PrivilegedActionException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
我们应该修改为:
1 @Autowired
2 private ILDAPDao ldapDao;
3
4 @WebMethod(operationName = "getLdapDao")
5 public ILDAPDao getLdapDao() {
6 return ldapDao;
7 }
参考资料:
1. Spring bug:https://jira.springsource.org/browse/SPR-5652
2. Spring与JAX-WS整合的关键:http://stevendu.iteye.com/blog/1326251
3. Spring+Hibernate+Struts的web应用程序移植到weblogic的问题:http://blog.csdn.net/zhizhesky/article/details/1634908