의존성 주입입니다. 이는 필요한 객체를 직접 생성하는 것이 아닌 외부로부터 객체를 받아서 사용하는 것이다.
이를 통해 객체간의 결합도를 줄이고 코드의 재사용성을 높일 수 있습니다.
의존성 주입은 생성자 주입, 수정자 주입, 필드 주입 3가지가 있다.
이중 Spring에서 권장하는 의존성 주입 방법은 생성자를 통한 주입 방법이다.
이유는 1. 순환 참조 방지 2. 불변성 가짐 3. 테스트에 용이 하기 때문이다.
@Service
public class UserServiceImpl implements UserService{
private UserRepository userRepository;
private MemberService memberService;
public UserServiceImpl(){
this.userRepository = new UserRepository();
this.memberService = new MemberService();
}
}
@Service
public class UserServiceImpl implements UserService{
private UserRepository userRepository;
private MemberService memberService;
@Autowired // 생략 가능
public UserServiceImpl(UserRepository userRepository, MemberService memberService){
this.userRepository = userRepository;
this.memberService = memberService;
}
}
생성자 주입은 호출 시점에 1회 보장
주입받는 객체의 변화가 없거나 반드시 객체의 주입이 필요한 경우 강제하기 위해 사용 가능
@Service
public class UserServiceImpl implements UserService{
private UserRepository userRepository;
private MemberService memberService;
@Autowired
public setUserRepository(UserRepository userRepository){
this.userRepository = userRepository;
}
@Autowired
public setMemberService(MemberService memberService){
this.memberService = memberService;
}
}
@Autowired로 주입할 대상 없는 경우(빈에 존재하지 않는 경우) 오류 발생
주입 대상 없도록 하려면 @Autowired(required = falase) 설정 가능
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;
@Autowired
private MemberService memberService;
}
외부에서 변경이 불가능
테스트 코드에서 Mock데이터 사용해 주입하면 안됨
어플리케이션의 작동과 무관한 테스트 코드나 설정을 위해서만 사용
스프링 부트는 BasicErrorController 가 제공하는 기본 정보들을 활용하여 API를 생성해준다.
예외가 발생해서 WAS까지 가는 순간 상태 코드는 무조건 500이다.
하지만 예외종류는 많고 400, 404 등 다른 상태코드도 전달하고 싶다.
HandlerExceptionResolver를 통해 동작 방식을 변경할 수 있다.
public MyHandlerExceptionResolver implements HandlerExceptionResolver{
public ModelAndView resolverException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex){
try{
if(ex instanceof IllegalArgumentException) {
log.info("IllegalArgumentException resolver to 400");
response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());
return new ModelAndView();
}
}catch (IOException e) {
log.error("resolver ex", e);
}
return null;
}
}

단순 구현이 아니라 등록 해줘야 한다.
@Configuration
public class WebConfig implements WebMvcCongfigurer{
// Exception Resolver 등록
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
resolvers.add(new MyHandlerException());
}
}
public class TestHandlerException implements HandlerExceptionResolver{
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public ModelAndView resolveEx(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex){
if(ex instanceof TestExcpetion){
String acceptHeader = request.getHeader("accept");
response.setStatus(HttpServletResponse.SC_FORBBIDDEN);
if("application/json".equals(acceptHeader)){
Map<String, Object> errorResult = new HashMap<>();
errorResult.put("예외 종류", ex.getClass());
errorResult.put("예외메세지", ex.getMessage());
String result = null;
try{
result = objectMapper.writeValueAsString(errorResult);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().write(result);
return new ModelAndView();
}catch (JsonProccessingException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}else {
new ModelAndView("/500.html");
}
}
return null;
}
}
@ExceptionHandler가 하나의 클래스에 대한 것이면, @ControllerAdvice는 모든 @Controller 즉, 전역에서 발생하는 예외를 처리하는 어노테이션이다.
@RestControllerAdvice
public class Myadvice{
@ExceptionHandler(NullPointException.class)
public Object nullex(Exception e){
System.out.println(e.getClass());
return "hi";
}
}
먼저 @RestControllerAdvice로 클래스를 만들고
그 이후 @ExceptionHandler로 처리하고 싶은 예외를 잡아 처리하면 된다.
이러면 모든 패키지 전역에 있는 컨트롤러를 다 잡아준다.
💡
@RestControllerAdvice는@ControllerAdvice와 동일한 역할을 하지만@ResponseBody를 통해 객체를 리턴할 수도 있다
✏️@ExceptionHandler({NullPointException.class, CustomException.class})이렇게 2개 이상도 사용 가능, NullPointException이 발생하면@ExceptionHandler(NullPointException.class)메소드 호출
Controller 내에서의 @ExceptionHandler사용
아주 유익한 내용이네요!