엔터프라이즈 프레임워크 준비
다음과 같은 프레임워크를 다루기 전에 Spring, 이해하는 것이 필수적입니다. 그 기반이 되는 아키텍처 패턴: 의존성 주입 e 통제의 역전.
무엇을 배울 것인가
- 제어 반전(IoC)
- 의존성 주입(DI)
- 패턴 저장소 및 서비스
- 스프링 프레임워크 준비
제어 반전(IoC)
IoC를 사용하면 확인하다 종속성 생성 및 관리 애플리케이션 코드에서 외부 컨테이너로 "역전"됩니다.
// SENZA IoC: l'applicazione crea le dipendenze
class UserService {
private UserRepository repository;
public UserService() {
// La classe decide come creare la dipendenza
this.repository = new MySqlUserRepository();
}
}
// CON IoC: le dipendenze vengono iniettate dall'esterno
class UserService {
private final UserRepository repository;
// La dipendenza è fornita da un container esterno
public UserService(UserRepository repository) {
this.repository = repository;
}
}
의존성 주입
// 1. CONSTRUCTOR INJECTION (preferito)
class OrderService {
private final OrderRepository repository;
private final PaymentService paymentService;
public OrderService(OrderRepository repository, PaymentService paymentService) {
this.repository = repository;
this.paymentService = paymentService;
}
}
// 2. SETTER INJECTION
class OrderService {
private OrderRepository repository;
public void setRepository(OrderRepository repository) {
this.repository = repository;
}
}
// 3. FIELD INJECTION (non raccomandato senza framework)
class OrderService {
@Inject // Richiede framework DI
private OrderRepository repository;
}
간단한 DI 컨테이너
import java.util.*;
import java.util.function.Supplier;
// Semplice container DI
class DIContainer {
private Map<Class<?>, Supplier<?>> factories = new HashMap<>();
private Map<Class<?>, Object> singletons = new HashMap<>();
public <T> void register(Class<T> type, Supplier<T> factory) {
factories.put(type, factory);
}
public <T> void registerSingleton(Class<T> type, T instance) {
singletons.put(type, instance);
}
@SuppressWarnings("unchecked")
public <T> T get(Class<T> type) {
if (singletons.containsKey(type)) {
return (T) singletons.get(type);
}
Supplier<?> factory = factories.get(type);
if (factory == null) {
throw new RuntimeException("No registration for: " + type);
}
return (T) factory.get();
}
}
// Uso
public class Application {
public static void main(String[] args) {
DIContainer container = new DIContainer();
// Registra dipendenze
container.registerSingleton(UserRepository.class,
new InMemoryUserRepository());
container.register(UserService.class,
() -> new UserService(container.get(UserRepository.class)));
// Risolvi
UserService service = container.get(UserService.class);
}
}
패턴 저장소
// Interfaccia Repository
interface Repository<T, ID> {
Optional<T> findById(ID id);
List<T> findAll();
T save(T entity);
void delete(T entity);
boolean existsById(ID id);
}
// Implementazione specifica
interface UserRepository extends Repository<User, Long> {
Optional<User> findByEmail(String email);
List<User> findByRole(String role);
}
// Implementazione concreta
class JpaUserRepository implements UserRepository {
// Implementazione con JPA/JDBC
}
class InMemoryUserRepository implements UserRepository {
private Map<Long, User> storage = new HashMap<>();
private long nextId = 1;
@Override
public Optional<User> findById(Long id) {
return Optional.ofNullable(storage.get(id));
}
@Override
public User save(User user) {
if (user.getId() == null) {
user.setId(nextId++);
}
storage.put(user.getId(), user);
return user;
}
// ... altri metodi
}
레이어 아키텍처
// LAYER 1: Controller (gestisce richieste HTTP)
class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
public Response createUser(CreateUserRequest request) {
User user = userService.createUser(request);
return Response.ok(user);
}
}
// LAYER 2: Service (business logic)
class UserService {
private final UserRepository repository;
private final EmailService emailService;
public UserService(UserRepository repository, EmailService emailService) {
this.repository = repository;
this.emailService = emailService;
}
public User createUser(CreateUserRequest request) {
// Validazione
if (repository.findByEmail(request.getEmail()).isPresent()) {
throw new UserAlreadyExistsException();
}
// Creazione
User user = new User(request.getName(), request.getEmail());
User saved = repository.save(user);
// Side effect
emailService.sendWelcome(saved);
return saved;
}
}
// LAYER 3: Repository (accesso dati)
// Già definito sopra
다음 단계: Spring 프레임워크
Spring으로 무엇을 배울 것인가
- 스프링 코어: IoC 컨테이너, Bean, @Autowired
- 스프링부트: 자동 구성, 스타터
- 스프링 데이터: JPA, 몽고DB, 레디스
- 스프링 MVC: REST API, @Controller
- 스프링 시큐리티: 인증, 승인
// Con Spring Boot, il codice diventa molto più semplice
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<User> createUser(@RequestBody CreateUserRequest request) {
User user = userService.createUser(request);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
}
@Service
public class UserService {
@Autowired
private UserRepository repository;
// Business logic...
}
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}
축하해요!
Java 과정을 완료했습니다! 이제 해결할 수 있는 탄탄한 기반이 생겼습니다. Spring, Jakarta EE 또는 Quarkus와 같은 엔터프라이즈 프레임워크.







