@Component와 그 파생 애노테이션들(@Controller, @Service, @Repository)을 사용하면 @ComponentScan 어노테이션에 의해서 Spring Framework가 Bean을 자동으로 등록하는 데 사용된다고 알아보았었습니다.
일반적으로는 이러한 자동 등록을 활용하는 것이 좋습니다.
왜냐하면 프로젝트 규모가 커지면 커질수록 등록해야 할 Bean은 점점 많아지기 때문에 자동 등록을 사용하면 아주 편리기 때문입니다.
그러나 Bean 수동 등록이 필요할 때가 있습니다.
Bean 수동 등록란❓
Bean 수동 등록이 필요할 때가 있다고 했는데, 언제 필요할까요❓
수동 등록은 일반적으로 기술적인 문제를 해결하거나, 공통적인 관심사를 처리할 때 유용합니다.
수동 등록의 예
- 기술 지원 Bean
- 공통적인 기능을 제공하는 Bean. 예를 들어, 공통 로그 처리, 보안 설정 등을 포함합니다.
- 커스텀 초기화 로직
- 특정 초기화 로직이 필요한 경우 수동으로 Bean을 정의하여 세밀한 제어가 가능합니다.
비즈니스 로직 Bean 보다는 그 수가 적기 때문에 수동으로 등록하기 부담스럽지 않습니다. 또한 수동등록된 Bean에서 문제가 발생했을 때 해당 위치를 파악하기 쉽다는 장점이 있습니다.
Bean 수동 등록 방법
1. @Configuration 및 @Bean 사용
@Configuration
public class PasswordConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
- Bean으로 등록하고자 하는 객체를 반환하는 메서드를 선언하고 @Bean을 설정합니다.
- Bean을 등록하는 메서드가 속한 해당 클래스에 @Configuration을 설정합니다.
위 코드에서 passwordEncoder() 메서드는 BCryptPasswordEncoder 객체를 생성하여 Spring 컨테이너에 Bean으로 등록합니다.
PasswordEncoder 란❓
Spring Security에서 제공하는 인터페이스로, 비밀번호를 안전하게 처리하기 위한 암호화 및 인코딩을 담당합니다.
비밀번호를직접 저장하거나 비교할 때평문으로 다루는 것은 보안상의 위험이 있으므로, PasswordEncoder를 사용하여 비밀번호를 안전하게 변환하고 저장합니다.
2. Spring IoC Container에 Bean저장
// 1. @Bean 설정된 메서드 호출
PasswordEncoder passwordEncoder = passwordConfig.passwordEncoder();
// 2. Spring IoC 컨테이너에 빈 (passwordEncoder) 저장
// passwordEncoder -> Spring IoC 컨테이너
Spring 서버가 시작될 때, @Configuration 클래스가 Component Scan에 의해 스캔되고, @Bean 메서드가 호출되어 반환된 객체는 Spring IoC 컨테이너에 Bean으로 저장됩니다.
@Bean 어노테이션이 설정된 메서드명은 Bean의 이름이 됩니다. 따라서, 위의 예제에서 passwordEncoder() 메서드는 "passwordEncoder"라는 이름의 Bean을 Spring IoC 컨테이너에 등록합니다.
Bean 수동 등록 확인
@Configuration
public class PasswordConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
앞서 알아보았던 비밀번호를 암호화할 때 사용하는 PasswordEncoder의 구현체 BCryptPasswordEncoder를 Bean으로 수동 등록 해보겠습니다.
@SpringBootTest
public class PasswordEncoderTest {
@Autowired
PasswordEncoder passwordEncoder;
@Test
@DisplayName("수동 등록한 passwordEncoder를 주입 받아와 문자열 암호화")
void test1() {
String password = "ZINU's password";
// 암호화
String encodePassword = passwordEncoder.encode(password);
System.out.println("encodePassword = " + encodePassword);
String inputPassword = "ZINU";
// 복호화를 통해 암호화된 비밀번호와 비교
boolean matches = passwordEncoder.matches(inputPassword, encodePassword);
System.out.println("matches = " + matches);
}
}
등록한 passwordEncoder ‘Bean’을 사용하여 문자열을 암호화 해보겠습니다. 위 코드를 기준으로 Test 코드를 실행해 보면 결과는 다음과 같습니다.
평문과 암호화 된 비밀번호를 matches() 메서드로 비교했기 때문에 false가 나오는 것을 확인해 볼 수 있습니다. 따라서 Bean이 올바르게 동작하고 있음을 알 수 있습니다.
passwordEncoder.encode()
passwordEncoder.encode(password)
passwordEncoder.encode() 메서드는 평문 비밀번호를 암호화된 형태로 변환합니다. Spring Security의 다양한 구현체가 지원되며, 비밀번호 검증 시 matches() 메서드와 함께 사용됩니다.
passwordEncoder.matches()
passwordEncoder.matches(rawPassword, encodedPassword)
passwordEncoder.matches() 메서드는 Spring Security에서 제공하는 PasswordEncoder 인터페이스의 한 메서드로, 주로 비밀번호의 유효성을 검증하는 데 사용됩니다.
이 메서드는 암호화된 비밀번호와 사용자가 입력한 비밀번호를 비교하여 일치 여부를 확인합니다.
passwordEncoder.matches(rawPassword, encodedPassword) 메서드는 두 가지 인자를 받습니다.
- rawPassword
- 사용자가 입력한 비밀번호 (평문 비밀번호)
- encodedPassword
- 데이터베이스에 저장된 암호화된 비밀번호
'Framework > Spring\Spring boot' 카테고리의 다른 글
[Spring Boot] 같은 타입의 Bean이 두 개 이상일 때 처리 방법 (0) | 2024.07.28 |
---|---|
[Spring] Spring에서 빈 이름 결정 방식 (0) | 2024.07.28 |
[Spring] Spring IoC Container와 Bean 알아보기 (0) | 2024.07.24 |
[Spring] Spring MVC: HTTP 요청 데이터의 객체 변환 방법 (@ModelAttribute vs @RequestBody) (2) | 2024.07.23 |
[Spring] Spring MVC : HTTP 요청으로 데이터 받기 (URL, Query String) (1) | 2024.07.23 |