Jersey 2.0에서의 의존성 주입
Jersey 1.x의 지식 없이 처음부터 시작해서 Jersey 2.0 프로젝트에서 의존성 주입을 설정하는 방법을 이해하는 데 어려움을 겪고 있습니다.
HK2가 Jersey 2.0에서 이용 가능한 것도 알고 있습니다만, Jersey 2.0 통합에 도움이 되는 문서를 찾을 수 없는 것 같습니다.
@ManagedBean
@Path("myresource")
public class MyResource {
@Inject
MyService myService;
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* @return String that will be returned as a text/plain response.
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/getit")
public String getIt() {
return "Got it {" + myService + "}";
}
}
@Resource
@ManagedBean
public class MyService {
void serviceCall() {
System.out.print("Service calls");
}
}
pom.xml
<properties>
<jersey.version>2.0-rc1</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jax-rs-ri</artifactId>
</dependency>
</dependencies>
컨테이너를 기동하여 리소스를 제공할 수 있지만 MyService에 @Inject를 추가하는 즉시 프레임워크에서 예외가 발생합니다.
SEVERE: Servlet.service() for servlet [com.noip.MyApplication] in context with path [/jaxrs] threw exception [A MultiException has 3 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=MyService,parent=MyResource,qualifiers={}),position=-1,optional=false,self=false,unqualified=null,1039471128)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.noip.MyResource errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on com.noip.MyResource
] with root cause
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=MyService,parent=MyResource,qualifiers={}),position=-1,optional=false,self=false,unqualified=null,1039471128)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
나의 스타터 프로젝트는 GitHub에서 구할 수 있다: https://github.com/donaldjarmstrong/jaxrs
하다를 가 있어요.AbstractBinder
JAX-RS의바인더는 종속성 주입이 클래스를 만드는 방법을 지정합니다.
public class MyApplicationBinder extends AbstractBinder {
@Override
protected void configure() {
bind(MyService.class).to(MyService.class);
}
}
@Inject
의 또는 되었다.MyService.class
.MyService
이 바인더를 사용하려면 JAX-RS 어플리케이션에 등록해야 합니다.고객님의 고객명web.xml
JAX-RS를 사용하다
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.mypackage.MyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyApplication</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
「 」의 실장MyApplication
(상기 클래스 )init-param
를 참조해 주세요.
public class MyApplication extends ResourceConfig {
public MyApplication() {
register(new MyApplicationBinder());
packages(true, "com.mypackage.rest");
}
}
위치도 REST를 참조하십시오).MyResource
를 합니다.packages()
메서드 콜
일단 수락 답변에 대한 코멘트에 대한 답변입니다.
바인드란 무엇인가?인터페이스와 구현이 있으면 어떻게 될까요?"
단단 it라고 쓰여 있다.bind( implementation ).to( contract )
수 ..in( scope )
의.PerLookup
싱글톤으로 하시면
bind( implementation ).to( contract ).in( Singleton.class );
'아주머니'라는 것도 있어요.RequestScoped
(사용가능)
, 「 」, 「 」bind(Class).to(Class)
, , 을 있습니다.bind(Instance).to(Class)
자동으로 싱글톤이 됩니다.
승인된 답변에 추가
AbstractBinder
web.xml을 하지 않음)ResourceConfig
패키지 스캔에서는 바인더가 검출되지 않는 것 같습니다.
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
your.packages.to.scan
</param-value>
</init-param>
아니면 이것도
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
com.foo.YourBinderImpl
</param-value>
</init-param>
이 기능을 이용하려면 , 다음의 기능을 실장할 필요가 있었습니다.
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.Provider;
@Provider
public class Hk2Feature implements Feature {
@Override
public boolean configure(FeatureContext context) {
context.register(new AppBinder());
return true;
}
}
@Provider
에는 ""가 되어야 합니다.Feature
패키지 스캔에 의해 픽업됩니다. 패키지 스캔을 하지 않고, 「」를 할 수 .Feature
web.xml
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
com.foo.Hk2Feature
</param-value>
</init-param>
...
<load-on-startup>1</load-on-startup>
</servlet>
참고 항목:
- Jersey를 사용한 커스텀 메서드 파라미터 주입
- 저지 요청 컨텍스트에 개체를 주입하려면 어떻게 해야 합니까?
- 저지/hk2 어플리케이션에서 Entity Manager를 올바르게 설정하려면 어떻게 해야 합니까?
- 싱글톤에 대한 범위 주입 요청
Jersey 문서의 일반적인 정보는
갱신하다
공장
승인된 답변의 기본 바인딩 외에도 보다 복잡한 작성 로직을 가질 수 있고 컨텍스트 정보를 요구할 수 있는 공장도 있습니다.예를들면
public class MyServiceFactory implements Factory<MyService> {
@Context
private HttpHeaders headers;
@Override
public MyService provide() {
return new MyService(headers.getHeaderString("X-Header"));
}
@Override
public void dispose(MyService service) { /* noop */ }
}
register(new AbstractBinder() {
@Override
public void configure() {
bindFactory(MyServiceFactory.class).to(MyService.class)
.in(RequestScoped.class);
}
});
그럼 주사하면 돼MyService
리소스 클래스로 이동합니다.
선택한 답변은 조금 전 날짜입니다.커스텀 HK2 바인더의 모든 바인딩을 선언하는 것은 실용적이지 않습니다.Tomcat을 사용하고 있는데 종속성을 하나만 추가하면 됩니다.Glassfish용으로 설계되었지만 다른 용기에 완벽하게 들어갑니다.
<dependency>
<groupId>org.glassfish.jersey.containers.glassfish</groupId>
<artifactId>jersey-gf-cdi</artifactId>
<version>${jersey.version}</version>
</dependency>
컨테이너도 올바르게 구성되어 있는지 확인합니다(설명서 참조).
늦었지만 이게 도움이 됐으면 좋겠어요.
JAX RS는 다음과 같이 정의되어 있습니다.
@Path("/examplepath")
@RequestScoped //this make the diference
public class ExampleResource {
그러면 드디어 코드로 다음을 주입할 수 있습니다.
@Inject
SomeManagedBean bean;
저 같은 경우에는SomeManagedBean
는 Application Scope 빈입니다.
이게 누구에게나 도움이 됐으면 좋겠어.
Oracle은 JAX-RS를 CDI와 결합할 때 삽입되는 모든 유형에 @Path 주석을 추가할 것을 권장합니다.http://docs.oracle.com/javaee/7/tutorial/jaxrs-advanced004.htm 이것은 완벽하지 않지만(예: 부팅 시 Jersey에서 경고를 받는 등), 저는 이 경로를 선택하기로 결정하였습니다.이로 인해 바인더 내에서 지원되는 모든 유형을 유지할 필요가 없습니다..
예를 들어:
@Singleton
@Path("singleton-configuration-service")
public class ConfigurationService {
..
}
@Path("my-path")
class MyProvider {
@Inject ConfigurationService _configuration;
@GET
public Object get() {..}
}
Guice를 사용하는 것을 선호하며 모든 바인딩을 선언하지 않으려면 다음 어댑터를 사용해 보십시오.
저는 이 기능을 통해AbstractBinder
웹 응용 프로그램에 다음과 같은 종속성이 포함되어 있는 경우(Tomcat 8.5, Jersey 2.27에서 실행):
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext.cdi</groupId>
<artifactId>jersey-cdi1x</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey-version}</version>
</dependency>
CDI 1.2 / CDI 2.0에서 작동합니다(각각 용접 2/3 사용).
jersey restful 서비스에 대한 의존관계가 필요하며 Tomcat이 서버입니다.여기서 ${discloss.version}은 2.29.1입니다.
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0.SP1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
기본 코드는 다음과 같습니다.
@RequestScoped
@Path("test")
public class RESTEndpoint {
@GET
public String getMessage() {
언급URL : https://stackoverflow.com/questions/16216759/dependency-injection-with-jersey-2-0
'programing' 카테고리의 다른 글
열기 사용 시 모듈 cv2를 찾을 수 없음이력서 (0) | 2022.10.29 |
---|---|
Python에 사용할 IDE는 무엇입니까? (0) | 2022.10.29 |
"SELECT UNION SELECT" 쿼리를 정렬 기준으로 독립 오더로 지정하시겠습니까? (0) | 2022.10.29 |
shell 명령을 사용하여 mysql 데이터베이스를 삭제하는 방법 (0) | 2022.10.28 |
Java: Thread.current스레드().sleep(x)와실.sleep(x) (0) | 2022.10.28 |