@Repository? @Service?
Repository? Service?
Spring Framework
μμλ IoC
컨ν
μ΄λμ Context
λ₯Ό λ±λ‘νλ μ¬λ¬κ°μ§ λ°©λ²μ΄ μλ€. Xml Config
λ±λ‘, @Configuration
λ±λ‘, ꡬν ν΄λμ€μ @Component
, @Service
, @Repository
λͺ
μ λ±λ±(Component, Service, Repository μ°¨μ΄λ λ§ν¬ κΈ μ°Έμ‘°) μ°Έμ‘°λ κΈμμ μ€λͺ
νλ€ μνΌ, μ΄λ μ΄λ
Έν
μ΄μ
μ μ¬μ©νλκ°μ, org.springframework.stereotype
ν¨ν€μ§μ μ΄λ
Έν
μ΄μ
μ IoC
컨ν
μ΄λμ ν΄λμ€λ₯Ό Context
λ‘ λ±λ‘ν΄μ£Όλ κΈ°λ₯μ νλ€.
μ€μ λ‘, org.springframework.stereotype
ν¨ν€μ§μ @Component
, @Service
, @Repository
, @Controller
μ΄λ
Έν
μ΄μ
ꡬν μ½λλ₯Ό 보면 λ€μκ³Ό κ°λ€.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
@AliasFor(annotation = Component.class)
String value() default "";
}
Controller, Service, Repository μ΄λ
Έν
μ΄μ
λͺ¨λ, @Component
μ΄λ
Έν
μ΄μ
μ΄ λͺ
μ λμ΄μμμ νμΈ ν μ μμΌλ©°, @AliasFor
λ‘ λ¬Άμ¬μμμ νμΈ ν μ μλ€. μ΄λ 곧 μΈ μ΄λ
Έν
μ΄μ
λͺ¨λ @Component
μ΄λ
Έν
μ΄μ
κ³Ό κ°μ κΈ°λ₯μ νλ€λκ²μ νμΈ ν μ μμλ€. μ¦ μΈ μ»΄ν¬λνΈμ μ°¨μ΄λ κ·Έμ @Component
μ μν μ λͺ
μνλκ²μ΄ μ΄λ
Έν
μ΄μ
λ€μ μν μ΄λΌκ³ μ΄ν΄ ν μ μλ€.
βκ·ΈλΌ Repositoryλ μ΄λ ν΄λμ€μ λͺ μνκ³ , Serviceλ μ΄λ ν΄λμ€μ λͺ μν΄μΌ νλμ? π€β
λ§€μ° νλ₯ν μ§λ¬Έμ΄λΌκ³ ν μ μλ€. μ¬μ€ νμκ° μ€νλ§ νλ μμν¬μ λν μ΄ν΄λκ° μ μμ λΉμμλ, κΈ°λ₯μ μΌλ‘ μ°¨μ΄κ° μμΌλ μ λΆ @Component
μ΄λ
Έν
μ΄μ
μΌλ‘ λͺ
μνμ¬ IoC
컨ν
μ΄λμ Context
λ₯Ό λ±λ‘νμλ€. νμ§λ§ κ°λ°μ νΌμμ νλκ²μ΄ μλλ©°, μ
μΌλ‘ μ£Όκ³ λ°λ λνλ³΄λ€ μ½λλ‘ μ£Όκ³ λ°λ λνκ° ν¨μ¬ μ€μνλ―λ‘, λͺ
μ
λΌλ κ°λ
μ΄ κ΅μ₯ν μ€μνλ€.
λ¨μλͺ
λ£νκ² λ§ νμλ©΄, Repository
λ λ§ κ·Έλλ‘, Resource
λ₯Ό μ£Όκ³ λ°λ μν μ νλ μΈν°νμ΄μ€μ λͺ
μνμ¬μΌ νλ€. λνμ μΌλ‘λ DB CRUD
μ μλν¬μΈνΈλ₯Ό νλ μΈν°νμ΄μ€μ λͺ
μνλ€. λνμ μΌλ‘ MyBatis
μ κ°μ SQLMapper
νλ μμν¬λ₯Ό μ°λνμ¬ μ¬μ© ν λ λ€μκ³Ό κ°μ Repsository
Context
λ€μ΄ λ§μ΄ μ‘΄μ¬νλ€.
@Repository
public interface UserRepository {
@Select("SELECT * FROM user WHERE USER_ID = #{userId}")
Optional<User> findByUserId(String userId);
@Update("UPDATE user SET USER_NAME = #{userName}, PASSWORD = #{password} WHERE USER_ID = #{userId}")
User updateUser(User user);
@Delete("DELETE FROM user WHERE USER_ID = #{userId}")
void deleteUserByUserId(String userId);
@Insert("INSERT INTO user(USER_ID, USER_NAME, PASSWORD) VALUES (#{userId}, #{userName}, #{password})")
User createUser(User user);
}
ν΄λΉ μΈν°νμ΄μ€λ User λΌλ ν μ΄λΈμ κ°μ κ°μ Έμ€κ±°λ, μμ±νλ μ μ₯μμ μν μ νλ€. λ¨μνκ² μ μ₯νκ³ , κ°μ Έμ€λ μν λ§ μννλ κ²μ΄λ€. μ¦ λ‘μ§μ΄ μ‘΄μ¬ν΄μλ μλλ€.
Repository
μ ꡬν λΉμ¦λμ€ λ‘μ§κ°μ μ€κ°μ μν μ ν΄ μ£Όλ κ²μ΄, Service
μ μν μ΄λ€. (λ¬Όλ‘ Service
λ λ€λ₯Έ μ¬λ¬ κΈ°λ₯μ μ 곡νλ κ°κ°μ§ Context
λ‘ κ΅¬νλ μ μλ€. μ§κΈμ DB CRUD κΈ°μ€μΌλ‘ μ€λͺ
νλ€.)
public interface UserService {
Optional<User> getUserById(String userId);
User createUser(User user);
User updateUser(User user);
void deleteUser(String userId);
}
@Service
public class UserServiceImpl implements UserService {
private final UserRepository repository;
public UserServiceImpl(UserRepository repository) {
this.repository = repository;
}
@Override
public Optional<User> getUserById(String userId) {
return repository.findByUserId(userId);
}
@Override
public User createUser(User user) {
repository.createUser(user);
}
@Override
public User updateUser(User user) {
return repository.updateUser(user);
}
@Override
public void deleteUser(String userId) {
repository.deleteUserByUserId(userId);
}
}
λκ° μ΄λ κ² Service
κ° κ΅¬νλμ΄, λΉμ¦λμ€ λ‘μ§μμ μ¬μ©λλ€. μ΄λ κ²λ§ λκ³ λ³΄λ©΄, λ¬Έλ μ΄λ° μκ°μ΄ λ€ μ μλ€.
βκ·Έλ₯ Repositoryμ μλ λ©μλ κ°λ€ μ΄κ±° μλμΌ? μ΄ μ§κ±°λ¦¬λ₯Ό μ ν΄?β
νμκ° Spring Framework
λ₯Ό νμ©ν΄ μ²μ κ°λ°μ νμ λ, κ°μ₯ λ¨Όμ λ€μλ μκ°μ΄λ€. μλμ μμ λ₯Ό ν΅ν΄ ν΄λΉ ν¨ν΄μ΄ κ°λ°μ νλ©΄μ μ΄λ€ μ΄λμ μ»μ μ μλμ§ νμΈ ν΄ λ³΄μ.
@RestController
@RequiredArgsConstructor
public class Controller {
private final UserService userService;
@RequestMapping(method = RequestMethod.POST, path = "/createUser", params = { "userId", "userName", "password" })
public ResponseEntity<User> createUser(@RequestParam String userId, @RequestParam String userName, @RequestParam String password) throws ResponseStatusException {
// κΈμ§λ USER_IDλ‘ μμ± μμ²μ΄ λ€μ΄μμ κ²½μ° νν°λ§
if (IllegalUserList.contains(userId)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, String.format("Create User Failed, Illegal userId : [%s]", userId));
}
User user = new User(userId, userName, password);
return ResponseEntity.ok().body(userService.createUser(user));
}
}
λ§μ½ μμ κ°μ΄, DBμ CRUDλ₯Ό νκΈ° μ μ μ¬μ μμ
μ΄ νμν κ²½μ°κ° λ‘μ§μ ꡬμ±νλ©΄μ μκΈΈ μ μλ€. λ³ λ¬Έμ κ° μμ΄ λ³΄μ΄λ λ‘μ§μ΄μ§λ§, createUser()
λ©μλλ ν΄λΉ 컨νΈλ‘€λ¬μμλ§ μ¬μ©νλκ²μ΄ μλ, λ²μ©μ μΌλ‘ μ¬μ©λλ λ©μλμ΄λ€.
λ°λΌμ μλμ κ°μ΄ Service ꡬν λ©μλ λΆλΆμμ μ¬μ μμ μ ν΄μ£Όλ©΄, μ€λ³΅μ½λ λ°©μ§μ ν° μ΄λ°μ§ ν μ μλ€. ν΄λΉ μ¬μ μμ μ νν°λ§μ΄ λ μλ μκ³ , μΊμ±μ΄ λ μλ μλ€.
@Override
public void createUser(User user) throw IllegalArgumentException {
if (IllegalUserList.contains(userId)) {
throw new IllegalArgumentException(String.format("Create User Failed, Illegal userId : [%s]", userId));
}
repository.createUser(user);
}
λκΈλ¨κΈ°κΈ°