의존성 주입
프로젝트에서 회원가입 코드를 만들 때,
AuthController.java 에서 AuthService.java의 회원가입 메서드를 사용하려고 한다면
AuthController.java에 AuthService 오브젝트를 의존성 주입해야 한다.
즉, 아래에서 볼 수 있듯이
AuthController.java 파일에서 signup 메서드를 보면
authService.회원가입(user);
이렇게 AuthService의 회원가입 메서드를 활용하려고 한다면,
의존성 주입이 필요하다.
<AuthController.java> 파일
@RequiredArgsConstructor
@Controller
public class AuthController {
private final AuthService authService;
@PostMapping("/auth/signup")
public String signup(@Valid SignupDto signupDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
}
throw new CustomValidationException("유효성 검사 실패함", errorMap);
}else {
User user = signupDto.toEntity();
authService.회원가입(user);
return "auth/signin";
}
}
}
<AuthService.java> 파일
@RequiredArgsConstructor
@Service
public class AuthService {
private final UserRepository userRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Transactional
public User 회원가입(User user) throws RuntimeException{
String rawPassword = user.getPassword();
String encPassword = bCryptPasswordEncoder.encode(rawPassword);
user.setPassword(encPassword);
user.setRole("ROLE_USER"); // 관리자 ROLE_ADMIN
User userEntity = null;
userEntity = userRepository.save(user);
return userEntity;
}
}
이때 의존성 주입하는 3가지 방법을 알아보자.
(AuthSerivce.java는 @Service 어노테이션으로 ioc 처리 되어 있다는 전제하에 진행)
1.
AuthController.java에 아래처럼 의존성 설정을 한다.
@Autowired
private AuthService authService;
@Controller
public class AuthController {
@Autowired
private AuthService authService;
@PostMapping("/auth/signup")
public String signup(@Valid SignupDto signupDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
}
throw new CustomValidationException("유효성 검사 실패함", errorMap);
}else {
User user = signupDto.toEntity();
authService.회원가입(user);
return "auth/signin";
}
}
}
2. AuthController.java에 아래처럼 의존성 설정
private AuthService authService;
public AuthController(AuthService authService) {
this.authService = authService;
}
@Controller
public class AuthController {
private AuthService authService;
public AuthController(AuthService authService) {
this.authService = authService;
}
@PostMapping("/auth/signup")
public String signup(@Valid SignupDto signupDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
}
throw new CustomValidationException("유효성 검사 실패함", errorMap);
}else {
User user = signupDto.toEntity();
authService.회원가입(user);
return "auth/signin";
}
}
}
AuthController.java에는 @Controller가 붙어 있어서
스프링이 AuthController를 ioc 등록하는데(컨테이너 메모리에 로드)
즉, 이때 AuthController 객체를 만들기 때문에, 생성자가 필요하다.
그런데 위의 코드에서
public AuthController(AuthService authService) {
this.authService = authService;
}
이처럼 사용자가 정의한 생성자를 실행하려 보니깐,
매개변수로 AuthService 객체가 있다.
때문에, 스프링은 이미 ioc에 등록한 AuthService가 있다면
(즉, @Service 애노테이션으로 AuthService가 ioc되어 있다면)
위의 생성자에 AuthService 객체를 집어 넣어주기 때문에(의존성 주입)
AuthController.java에서 사용할 수 있다.
그런데 이렇게 매번 생성자를 입력하는 것은 귀찮기 때문에
세번째 방법을 소개한다.
3. AuthController.java 파일에서 아래처럼 의존성 설정한다.
위 2번째 방법과 차이점은,
생성자 만드는 코드를 없애고,
@RequiredArgsConstructor 어노테이션을 사용하고,
private AuthService authService 변수에
final 을 추가했다는 점이다.
@RequiredArgsConstructor
@Controller
public class AuthController {
private final AuthService authService;
@RequiredArgsConstructor
@Controller
public class AuthController {
private final AuthService authService;
@PostMapping("/auth/signup")
public String signup(@Valid SignupDto signupDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
}
throw new CustomValidationException("유효성 검사 실패함", errorMap);
}else {
User user = signupDto.toEntity();
authService.회원가입(user);
return "auth/signin";
}
}
}
private final AuthService authService;
이 코드에서 볼 수 있듯이
자바에서는 전역 변수에 final이 있으면
객체가 만들어질 때 초기화를 무조건 해줘야 한다. 즉 생성자가 필요하다.
그런데
@RequiredArgsConstructor 애노테이션은,
final이 있는 변수의 생성자를 자동으로 만들어준다.
이 방법이 편리하기 때문에, 프로젝트를 하면서 이 방법을 사용한다.
-끝-
참고 자료 : 이지업 강의 사이트 "스프링부트 SNS프로젝트 - 포토그램 만들기"