kgi*_*ibm 7 spring dependency-injection cxf jax-rs spring-boot
我正在使用cxf.jaxrs.classes-scan和cxf.jaxrs.classes-scan-packages将现有的vanilla JAX-RS应用程序JAR与Spring Boot应用程序包装在一起.当我作为JAR或者运行时maven spring-boot:run,依赖注入工作正常.当我作为WAR运行时(在WebSphere Liberty 17.0.0.2上),- @Injectable字段null在REST请求期间.
这是SpringBootApplication:
@SpringBootApplication(scanBasePackages = { "com.test" })
public class CustomerServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(CustomerServiceApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(CustomerServiceApplication.class);
}
}
Run Code Online (Sandbox Code Playgroud)
这是src/main/resources/application.properties:
cxf.path=/
cxf.jaxrs.classes-scan=true
cxf.jaxrs.classes-scan-packages=com.test,com.fasterxml.jackson.jaxrs.json
Run Code Online (Sandbox Code Playgroud)
这是Maven pom.xml(vanilla JAX-RS应用程序JAR是本地存储库中的customerservice-java):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>customerservice-springboot</groupId>
<artifactId>customerservice-springboot</artifactId>
<packaging>war</packaging>
<version>2.0.0-SNAPSHOT</version>
<name>Customer Service :: Spring Boot</name>
<!-- We need to use cxf-spring-boot-starter-jaxrs 3.2.0 because of https://issues.apache.org/jira/browse/CXF-7237
At the time of writing this code, the latest available version in Maven central
is 3.1.7 so we need to use the Apache snapshot repository. -->
<repositories>
<repository>
<id>apache.snapshots</id>
<name>Apache Development Snapshot Repository</name>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
<version>3.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>customerservice-java</groupId>
<artifactId>customerservice-java</artifactId>
<version>2.0.0-SNAPSHOT</version>
<classifier>jar</classifier>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Run Code Online (Sandbox Code Playgroud)
这是JAR项目中的Web服务:
package com.test;
import javax.inject.Inject;
import javax.ws.rs.CookieParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
@Path("/")
public class CustomerServiceRest {
@Inject
CustomerService customerService;
@GET
@Path("/byid/{custid}")
@Produces("text/plain")
public Response getCustomer(@PathParam("custid") String customerid, @CookieParam("token") String jwtToken) {
return Response.ok(customerService.getCustomerId(customerid)).build();
}
}
Run Code Online (Sandbox Code Playgroud)
这是豆子:
package com.test;
import javax.inject.Named;
@Named
public class CustomerService {
public String getCustomerById(String username) {
// ... implementation ..
return customerDoc.toJson();
}
}
Run Code Online (Sandbox Code Playgroud)
这是WAR日志输出:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.4.RELEASE)
INFO c.a.s.CustomerServiceApplication - Starting CustomerServiceApplication on 23fb5f5646c3 with PID 20 (/opt/ibm/wlp/usr/servers/defaultServer/apps/expanded/customerservice-springboot-2.0.0-SNAPSHOT.war/WEB-INF/classes started by root in /opt/ibm/wlp/output/defaultServer)
INFO c.a.s.CustomerServiceApplication - No active profile set, falling back to default profiles: default
INFO o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext - Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67e7ebcd: startup date [Wed Jul 19 19:36:12 UTC 2017]; root of context hierarchy
INFO o.s.b.f.x.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [META-INF/cxf/cxf.xml]
INFO o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO c.i.w.w.webapp - SRVE0292I: Servlet Message - [customerservice-springboot-2.0.0-SNAPSHOT]:.Initializing Spring embedded WebApplicationContext
INFO o.s.w.c.ContextLoader - Root WebApplicationContext: initialization completed in 3654 ms
INFO o.s.b.w.s.ServletRegistrationBean - Mapping servlet: 'dispatcherServlet' to [/]
INFO o.s.b.w.s.ServletRegistrationBean - Mapping servlet: 'CXFServlet' to [/*]
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'errorPageFilter' to: [/*]
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*]
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'httpPutFormContentFilter' to: [/*]
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'requestContextFilter' to: [/*]
INFO o.s.w.s.m.m.a.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67e7ebcd: startup date [Wed Jul 19 19:36:12 UTC 2017]; root of context hierarchy
INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO o.a.c.e.ServerImpl - Setting the server's publish address to be /
INFO o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
INFO c.a.s.CustomerServiceApplication - Started CustomerServiceApplication in 14.955 seconds (JVM running for 271.749)
INFO o.a.c.e.S.e.o.i.l.E.i.w.j.2.0.c.0.17.cl170220170523-1818(id=171)] - Setting the server's publish address to be /
Run Code Online (Sandbox Code Playgroud)
如果我能logging.level.org.springframework.beans.factory.support=TRACE在application.properties,我看到了依赖注入在应用程序启动工作:
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'customerService'
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'customerService'
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'customerService' to allow for resolving potential circular references
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'customerService' [...]
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'com.test.CustomerServiceRest'
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'customerService'
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'com.test.CustomerServiceRest'
Run Code Online (Sandbox Code Playgroud)
但是,当我发出REST请求时,我可以看到CustomerServiceRest在每个请求(System.out.println在构造函数中)创建了一个新实例,并且@Inject-able依赖项是null(在a中暂停NullPointerException).所以我想,也许加入@Singleton到CustomerServiceRest会的工作,而是一个新的对象仍然是对每个请求创建.
有谁知道如何使用单个Web服务bean或确保Spring注入所有依赖项?vanilla JAX-RS应用程序JAR本身不能承担任何Spring依赖项.
我能够通过不使用 Liberty 的 CXF(例如使用servlet& jspfeatures 而不是webProfile[引入 Liberty 的jaxrs功能] 的功能)并添加exclude = { DispatcherServletAutoConfiguration.class }到@SpringBootApplication注释来解决此问题。这仅适用于我的用例类型(例如微服务),其中 被DispatcherServlet安装为默认 servlet /,并且CXFServlet被安装cxf.path=/(从而创建/*URL 映射)。对于 Spring MVC 与 CXF 混合但 CXF 服务位于非根 URL 映射的其他情况,则exclude没有必要。我仍在研究如何让它与 Liberty 的 CXF 一起使用,如果我发现,我会更新这个答案。
| 归档时间: |
|
| 查看次数: |
907 次 |
| 最近记录: |