Jakarta JWS WebService无法注入Spring Bean问题求助
基于现有WSDL克隆SOAP服务端,技术栈为Java 11 + Spring Boot 2.7.13 + jakarta.xml.ws-api-4.0.1,通过org.codehaus.mojo>jaxws-maven-plugin-2.6生成相关类后,实现了CarregaImpl服务类:
import javax.inject.Inject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.springframework.web.context.support.SpringBeanAutowiringSupport; import jakarta.annotation.PostConstruct; import jakarta.jws.WebMethod; import jakarta.jws.WebService; import lombok.extern.java.Log; import lombok.extern.slf4j.Slf4j; import net.gencat.salut.sivec.external.cases.argo.model.Carrega; import net.gencat.salut.sivec.external.cases.argo.model.OrdreAltaDadesRegistre; @WebService(endpointInterface = "net.gencat.salut.sivec.external.cases.argo.model.Carrega") @Slf4j public class CarregaImpl implements Carrega { @Autowired private OrchestationAlta orchestationAlta; @Override @WebMethod(action = "alta") public OrdreAltaDadesRegistre alta(OrdreAltaDadesRegistre arg0, String arg1, String arg2) { // TODO Auto-generated method stub return orchestationAlta.altaArgo(arg0); } }
OrchestationAlta的实现类如下:
@Component public class OrchestationAltaImpl implements OrchestationAlta{ @Autowired private PatientService patientService; @Autowired private CaseService caseService; @Override public OrdreAltaDadesRegistre altaArgo(OrdreAltaDadesRegistre ordreAltaDadesRegistre) { try { PacientArgoDto pacienteArgoDto = PacientConverter.toPacienteArgoDto(ordreAltaDadesRegistre); PatientResponse patientResponse = patientService.createPatient(pacienteArgoDto); CaseArgoDto caseArgoDto = CaseConverter.toCaseArgoDto(ordreAltaDadesRegistre); CaseRequest caseRequest = CaseConverter.toCaseRequest(caseArgoDto,patientResponse); caseService.createCase(caseRequest); ordreAltaDadesRegistre.setCognom1(patientResponse.getFirstName()); ordreAltaDadesRegistre.setCognom2(patientResponse.getSurname()); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); if(Objects.nonNull(patientResponse.getDateOfbirth())) { ordreAltaDadesRegistre.setDataNaixament(patientResponse.getDateOfbirth().format(formatter)); } ordreAltaDadesRegistre.setError("0"); } catch (Exception e) { ordreAltaDadesRegistre.setError(null); } return ordreAltaDadesRegistre; } }
尝试过使用@PostConstruct、将@Autowired改为构造方法注入等方式,但orchestationAlta字段始终为null,请问哪里操作有误?
核心问题
CarregaImpl未被Spring容器纳入管理,导致Spring无法自动注入OrchestationAlta实例。虽然代码中引入了SpringBeanAutowiringSupport但未正确启用,且类上缺少Spring组件注解。
具体修复步骤
为
CarregaImpl添加Spring组件注解
在CarregaImpl类上添加@Service或@Component注解,让Spring识别并管理该类:@WebService(endpointInterface = "net.gencat.salut.sivec.external.cases.argo.model.Carrega") @Slf4j @Service // 或@Component public class CarregaImpl implements Carrega { // 原有代码保留 }启用Spring自动装配支持
由于JAX-WS的服务实例可能由JAX-WS容器创建而非Spring,需在CarregaImpl中添加@PostConstruct方法触发Spring的自动装配逻辑:@WebService(endpointInterface = "net.gencat.salut.sivec.external.cases.argo.model.Carrega") @Slf4j @Service public class CarregaImpl implements Carrega { @Autowired private OrchestationAlta orchestationAlta; @PostConstruct public void init() { SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); } // 原有业务方法保留 }确保SOAP端点由Spring托管
检查SOAP服务的发布配置,确保通过Spring来注册端点,而非直接使用JAX-WS原生API创建CarregaImpl实例。比如可以使用Spring的@Endpoint注解或者自定义配置类,保证CarregaImpl实例由Spring容器提供。构造方法注入优化(可选)
若偏好构造方法注入,可直接编写带参数的构造方法(Spring 4.3+无需@Autowired),同时保留上述自动装配初始化逻辑:@WebService(endpointInterface = "net.gencat.salut.sivec.external.cases.argo.model.Carrega") @Slf4j @Service public class CarregaImpl implements Carrega { private final OrchestationAlta orchestationAlta; public CarregaImpl(OrchestationAlta orchestationAlta) { this.orchestationAlta = orchestationAlta; } @PostConstruct public void init() { SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); } // 原有业务方法保留 }
额外检查项
- 确认
OrchestationAltaImpl的@Component注解生效,且所在包被Spring组件扫描覆盖(比如主启动类的@SpringBootApplication扫描范围包含该类所在包)。 - 检查
PatientService和CaseService的实现类也添加了@Service等Spring组件注解,避免连锁注入失败。
内容的提问来源于stack exchange,提问作者Reyfren

