Spring에서는 Bean을 등록하는 두 가지 방식이 존재합니다.
@Component
@Controller
@Service
@Repository
public class MyService {
// Spring이 자동으로 Bean으로 등록
}
@Configuration
public class MyConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
비즈니스 로직 Bean
package com.mywork.springauth.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration // Spring 설정 클래스임을 명시
public class PasswordConfig {
@Bean // Spring IoC 컨테이너에 Bean으로 등록
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
@Configuration : 이 클래스가 Spring 설정 클래스임을 표시@Bean : 메서드의 반환 객체를 Sprinf IoC 컨테이너에 등록passwordEncoder)// Spring 서버 시작 시
// 1. @Bean 설정된 메서드 호출
PasswordEncoder passwordEncoder = passwordConfig.passwordEncoder();
// 2. Spring IoC 컨테이너에 Bean 저장
// Key: "passwordEncoder" (메서드명)
// Value: BCryptPasswordEncoder 인스턴스
package com.mywork.springauth;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;
@SpringBootTest
public class PasswordEncoderTest {
@Autowired // Spring 컨테이너에서 passwordEncoder Bean 주입
PasswordEncoder passwordEncoder;
@Test
@DisplayName("수동 등록한 passwordEncoder를 주입받아 문자열 암호화")
void test1() {
String password = "mypassword1234";
// 암호화
String encodePassword = passwordEncoder.encode(password);
System.out.println("encodePassword = " + encodePassword);
String inputPassword = "password5678";
// 비밀번호 검증 (원본과 암호화된 비밀번호 비교)
boolean matches = passwordEncoder.matches(inputPassword, encodePassword);
System.out.println("matches = " + matches); // false (다른 문자열)
}
}
// Spring Security 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-security'
package com.mywork.springauth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class SpringAuthApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAuthApplication.class, args);
}
}
⚠️ 실제 운영 환경에서는 Security를 제외하지 않고 사용
싱글톤 패턴 활용
// 같은 문자열도 매번 다르게 암호화됨 (Salt 사용)
String pw1 = passwordEncoder.encode("1234");
String pw2 = passwordEncoder.encode("1234");
// pw1 != pw2 (값은 다르지만 matches()로 비교하면 true)
// 복호화 불가능 (단방향 해시)
// 원본을 알아낼 수 없고, matches()로만 검증 가능
@Autowired
PasswordEncoder passwordEncoder; // 인터페이스 타입
BCryptPasswordEncoder -> SCryptPasswordEncoder 변경시 Config만 수정| 구분 | 자동 등록 | 수동 등록 |
|---|---|---|
| 사용 시점 | 비즈니스 로직 Bean | 기술 지원 Bean |
| 개수 | 많음 | 적음 |
| Annotation | @Component,@Service,@Repository 등 | @Configuration + @Bean |
| 관리 난이도 | 쉬움 | 설정 파일 관리 필요 |
| 추적성 | 분산되어 있음 | 한 곳에 모여있어 명확 |