이 질문에 대한 답을 얻은 후 봄 세계에서 많은 변화가있었습니다. Spring은 컨트롤러에서 현재 사용자를 얻는 것을 단순화했습니다. 다른 빈의 경우 Spring은 저자의 제안을 채택하고 'SecurityContextHolder'의 주입을 단순화했습니다. 자세한 내용은 의견에 있습니다.
이것이 내가 끝낸 해결책입니다. SecurityContextHolder내 컨트롤러에서 사용하는 대신 SecurityContextHolder후드에서 사용하지만 코드에서 단일 클래스와 같은 클래스를 추상화 하는 것을 주입하고 싶습니다. 내 인터페이스를 롤링하는 것 외에는 이렇게 할 수있는 방법이 없습니다.
public interface SecurityContextFacade {
SecurityContext getContext();
void setContext(SecurityContext securityContext);
}
이제 내 컨트롤러 (또는 POJO)는 다음과 같습니다.
public class FooController {
private final SecurityContextFacade securityContextFacade;
public FooController(SecurityContextFacade securityContextFacade) {
this.securityContextFacade = securityContextFacade;
}
public void doSomething(){
SecurityContext context = securityContextFacade.getContext();
// do something w/ context
}
}
또한 인터페이스가 디커플링 지점이되기 때문에 단위 테스트가 간단합니다. 이 예에서는 Mockito를 사용합니다.
public class FooControllerTest {
private FooController controller;
private SecurityContextFacade mockSecurityContextFacade;
private SecurityContext mockSecurityContext;
@Before
public void setUp() throws Exception {
mockSecurityContextFacade = mock(SecurityContextFacade.class);
mockSecurityContext = mock(SecurityContext.class);
stub(mockSecurityContextFacade.getContext()).toReturn(mockSecurityContext);
controller = new FooController(mockSecurityContextFacade);
}
@Test
public void testDoSomething() {
controller.doSomething();
verify(mockSecurityContextFacade).getContext();
}
}
인터페이스의 기본 구현은 다음과 같습니다.
public class SecurityContextHolderFacade implements SecurityContextFacade {
public SecurityContext getContext() {
return SecurityContextHolder.getContext();
}
public void setContext(SecurityContext securityContext) {
SecurityContextHolder.setContext(securityContext);
}
}
마지막으로 프로덕션 Spring 구성은 다음과 같습니다.
<bean id="myController" class="com.foo.FooController">
...
<constructor-arg index="1">
<bean class="com.foo.SecurityContextHolderFacade">
</constructor-arg>
</bean>
모든 것의 의존성 주입 컨테이너 인 Spring이 비슷한 것을 주입하는 방법을 제공하지 않았다는 것은 조금 어리석은 것처럼 보입니다. 나는 SecurityContextHolderacegi에서 상속되었지만 여전히 여전히 이해 합니다. 문제는, 그것들이 너무 가깝다는 것입니다- SecurityContextHolder기본 SecurityContextHolderStrategy인스턴스 (인터페이스) 를 얻는 게터 만 있다면 그것을 주입 할 수 있습니다. 사실, 나는 심지어 그 효과에 대한 Jira 문제 를 열었습니다 .
마지막 한 가지-나는 이전에 내가 가진 대답을 크게 바 꾸었습니다. 궁금한 점이 있다면 역사를 확인하십시오.하지만 동료가 지적했듯이 이전 답변은 멀티 스레드 환경에서 작동하지 않습니다. 기본적으로 SecurityContextHolderStrategy사용되는 SecurityContextHolder기본은의 인스턴스이며 ThreadLocalSecurityContextHolderStrategy를에 저장 SecurityContext합니다 ThreadLocal. 따라서 SecurityContext초기화 시간에 Bean에 직접 직접 삽입하는 것이 좋은 아이디어는 아닙니다 ThreadLocal. 멀티 스레드 환경에서 매번 검색해야 할 수 있으므로 올바른 것을 검색해야합니다.