遗留JAX-WS WebService中spring-boot-starter-jdbc DAO对象未注入问题
核心问题1:组件扫描未开启导致Bean未注册
你的启动类GetItemsApplication在Y包下,@SpringBootApplication默认仅扫描启动类所在包及其子包下的注解类,你代码里的@ComponentScan被注释掉了,导致X包下的WebService实现类、Y.Z包下的Repository和数据源配置类都没有被Spring容器识别,无法创建对应Bean,自然无法完成注入。
修复方式
解开启动类的@ComponentScan注释,确保覆盖所有需要注册Bean的包路径:
@ComponentScan(basePackages={"X","Y"}) @SpringBootApplication public class GetItemsApplication { // 原有代码 }
核心问题2:JAX-WS端点实例不归Spring容器管理
你当前通过web.xml和sun-jaxws.xml配置WebService启动,这种模式下端点的实例是由JAX-WS运行时自行创建的,即便你给BServiceManager加了@Component注解,Spring容器中存在对应Bean,但实际处理SOAP请求的是JAX-WS自己创建的独立实例,这个实例不在Spring的管理范围内,@Autowired注解自然不会生效。
修复方式(二选一即可)
方案1:替换为Spring托管的端点导出方式(推荐)
删除web.xml和sun-jaxws.xml中的JAX-WS相关配置,新增配置类将Spring管理的WebService Bean直接导出为可用端点:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter; @Configuration public class JaxWsConfig { @Bean public SimpleJaxWsServiceExporter jaxWsServiceExporter() { SimpleJaxWsServiceExporter exporter = new SimpleJaxWsServiceExporter(); // 配置WebService的根路径,最终访问地址为根路径+服务名 exporter.setBaseAddress("http://0.0.0.0:8080/ws/"); return exporter; } }
配置完成后Spring会自动识别所有带@WebService注解的Spring Bean,将其导出为可用端点,处理请求的就是Spring托管的实例,依赖注入会正常生效。
方案2:保留原有web.xml配置,手动开启注入
如果你必须保留原有的web.xml和sun-jaxws.xml配置,可以让BServiceManager继承SpringBeanAutowiringSupport,JAX-WS创建实例时会自动触发Spring依赖注入:
@Component @WebService(name = "***",***) @BindingType("http://schemas.xmlsoap.org/wsdl/soap/http") @XmlSeeAlso({packagesxxx.class,...}) public class BServiceManager extends SpringBeanAutowiringSupport implements xxxxx { // 原有代码保留,@Autowired注解不需要修改 }
使用该方案需要确保你的项目中已经配置了Spring的ContextLoaderListener,让Web应用可以正确加载Spring上下文。
额外优化点
@Repository注解本身已经是@Component的派生注解,你的ItemRepository不需要同时加两个注解,保留@Repository即可。
内容的提问来源于stack exchange,提问作者jayFifth

