Jersey 2 에 Spring 구성 요 소 를 어떻게 주입 합 니까?
18729 단어 개발 틀
다음은 저지 2.0 과 스프링 3.0 버 전 을 예 로 들 자.
<dependency>
<groupId>org.glassfish.jersey.coregroupId>
<artifactId>jersey-serverartifactId>
<version>2.0version>
dependency>
<dependency>
<groupId>org.glassfish.jersey.containersgroupId>
<artifactId>jersey-container-servletartifactId>
<version>2.0version>
dependency>
<dependency>
<groupId>org.glassfish.jersey.extgroupId>
<artifactId>jersey-spring3artifactId>
<version>2.2version>
dependency>
코드 예제
// Spring Service
@Service
public class WorkServiceImpl implements WorkService {
...
}
@Path("/work")
public class WorkResource {
// Spring Autowired
@Autowired
private WorkService workService;
@Path("/")
@POST
@Produces(MediaType.TEXT_PLAIN)
public void accept(@BeanParam WorkVO work) {
workService.accept(work);
}
}
이 가능 하 다,~할 수 있다,...
일반적으로 위의 코드 에 있 는 workService 는 정상적으로 호출 될 수 있 습 니 다.그러나 프로젝트 에 WorkService 인터페이스 에 여러 개의 실현 클래스 가 있 으 면 Spring 환경 에서 인터페이스 형식(by Type)에 따라 주입 할 수 없고 이름(by Name)에 따라 만 주입 할 수 있 기 때문에@Service 에 beanName 을 추가 해 야 합 니 다.예 를 들 어:
@Service("weixinWorkService")
public class WeixinWorkServiceImpl implements WorkService {
...
}
@Service("appWorkService")
public class AppWorkServiceImpl implements WorkService {
...
}
이 때 WorkService 에 WeixinWorkServiceImpl 을 주입 하려 면 자바 x.annotation.Resource 주 해 를 사용 하여 코드 를 수정 하 는 것 이 먼저 생각 날 수 있 습 니 다.
@Path("/work")
public class WorkResource {
// Javax Resource
@Resource(name = "weixinWorkService")
private WorkService workService;
@Path("/")
@POST
@Produces(MediaType.TEXT_PLAIN)
public void accept(@BeanParam WorkVO work) {
workService.accept(work);
}
}
그러나 코드 를 실행 한 결과 콘 솔 에서 빈 포인터 이상 을 알 리 고 워 크 서비스 가 null 로 인 한 것 으로 확인 되 었 습 니 다.
나중에 일련의 시 도 를 통 해 관련 소스 코드 를 추적 한 결과 원래 Jersey-Spring 3 구성 요 소 는 Spring 의@Autowired 와@Qualifier 만 지원 하고@Resource 를 분석 하지 않 는 다 는 것 을 알 게 되 었 다.
Jersey-Spring 3 에서 주입 구성 요 소 를 분석 하 는 것 은 org.glasfish.jersey.server.spring.autowired Inject Resolver 류 입 니 다.
public class AutowiredInjectResolver implements InjectionResolver<Autowired> {
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> root) {
AnnotatedElement parent = injectee.getParent();
String beanName = null;
if(parent != null) {
// : @Qualifier , beanName
Qualifier an = parent.getAnnotation(Qualifier.class);
if(an != null) {
beanName = an.value();
}
}
return getBeanFromSpringContext(beanName, injectee.getRequiredType());
}
private Object getBeanFromSpringContext(String beanName, Type beanType) {
Class<?> bt = getClassFromType(beanType);
// : beanName , Spring
if(beanName != null) {
bean
return ctx.getBean(beanName, bt);
}
// : beanName ,
Map<String, ?> beans = ctx.getBeansOfType(bt);
// : bean bean, null。
// @Qualifier , , NPE。
if(beans == null || beans.size() != 1) {
LOGGER.warning(LocalizationMessages.NO_BEANS_FOUND_FOR_TYPE(beanType));
return null;
}
return beans.values().iterator().next();
}
}
원인 을 찾 으 면 해결 이 쉽다.
@Path("/work")
public class WorkResource {
// Autowired Qualifier
@Autowired
@Qualifier(name = "weixinWorkService")
private WorkService workService;
......
}
작은 매듭
4.567917.서로 다른 프레임 워 크 나 구성 요소 가 주석 에 대한 지원 범 위 는 다 를 수 있 습 니 다.평소에 Spring 을 많이 사용 하기 때문에 헷 갈 리 기 쉬 워 요.
4.567917.가능 한 한 통 일 된 기술 창 고 를 사용한다.예 를 들 어 특별한 상황 없 이 Spring 환경 은 SpringMVC 로 Jersey 를 교체 할 수 있다