@Transactional(readOnly = true)
@RequiredArgsConstructor
@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
@Transactional
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
Map<String, Object> attributes = super.loadUser(userRequest).getAttributes();
//resource Server로 부터 받아온 정보중 필요한 정보 추출.
...
}
}
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Import({CustomOAuth2UserService.class,
Auditor.class, QuerydslConfig.class, JpaAndEntityPackagePathConfig.class,
TestBootstrapConfig.class, BootstrapDataLoader.class, BCryptPasswordEncoder.class
})
class CustomOAuth2UserServiceWithDaoTest {
@MockBean
private DefaultOAuth2UserService defaultOAuth2UserService;
@Autowired
private DefaultOAuth2UserService customOAuth2UserService;
@Test
void loadUser() {
//given
...
given(defaultOAuth2UserService.loadUser(any(OAuth2UserRequest.class)))
.willReturn(new DefaultOAuth2User(null,
Map.of("id", 3, "login", "test-login", "email", "test-email", "image",
Map.of("link", "test-link")), "login"));
}
}
이렇게 하게 될 경우 DefaultOAuth2UserService타입의 빈이 두 개가 되기 때문에 주입 받을 때 필드명을 빈 이름으로 특정하거나 @Qualifier를 활용하여 구분해서 주입받아야 합니다.
@Configuration
public class DefaultOAuth2UserServiceConfig {
@Bean
public DefaultOAuth2UserService defaultOAuth2UserService() {
return new DefaultOAuth2UserService();
}
}
@Transactional(readOnly = true)
@RequiredArgsConstructor
@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
private final DefaultOAuth2UserService defaultOAuth2UserService;
@Transactional
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
Map<String, Object> attributes = defaultOAuth2UserService.loadUser(userRequest).getAttributes();
//resource Server로 부터 받아온 정보중 필요한 정보 추출.
...
}
}
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Import({CustomOAuth2UserService.class,
Auditor.class, QuerydslConfig.class, JpaAndEntityPackagePathConfig.class,
TestBootstrapConfig.class, BootstrapDataLoader.class, BCryptPasswordEncoder.class
})
class CustomOAuth2UserServiceWithDaoTest {
@MockBean
private DefaultOAuth2UserService defaultOAuth2UserService;
@Autowired
private DefaultOAuth2UserService customOAuth2UserService;
@Test
void loadUser() {
//given
...
given(defaultOAuth2UserService.loadUser(any(OAuth2UserRequest.class)))
.willReturn(new DefaultOAuth2User(null,
Map.of("id", 3, "login", "test-login", "email", "test-email", "image",
Map.of("link", "test-link")), "login"));
}
}
unable to register mock bean org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService expected a single matching bean to replace but found [defaultOAuth2UserService, partner42.moduleapi.service.user.CustomOAuth2UserService]
@MockBean
@Qualifier("defaultOAuth2UserService")
private DefaultOAuth2UserService defaultOAuth2UserService;
@Autowired
@Qualifier("customOAuth2UserService")
private DefaultOAuth2UserService customOAuth2UserService;
@Configuration
public class DefaultOAuth2UserServiceConfig {}
@Transactional(readOnly = true)
@RequiredArgsConstructor
@Service
@Qualifier("customOAuth2UserService")
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
@Configuration
@EnableWebSecurity
//Secured, PrePost 어노테이션 활성화
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Qualifier("customOAuth2UserService")
private final DefaultOAuth2UserService customOAuth2UserService;
src/main/java/lombok.config 파일을 만들어주세요.(resources가 아닙니다. src/main/java입니다!)
lombok.config에 다음 내용을 넣어주세요.
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
해당 옵션을 적용한 후에 빌드된 .class 파일을 확인해보면 다음과 같이 @Qulifier가 포함 된 것을 확인할 수 있습니다.