
Spring Framework는 자바 기반의 오픈소스 프레임워크로, 특히 기업용 애플리케이션 개발을 위한 다양한 기능을 제공함. Spring은 개발자의 생산성을 높이기 위해 설계되었으며, 의존성 주입(Dependency Injection, DI)과 관점 지향 프로그래밍(Aspect-Oriented Programming, AOP) 등의 개념을 활용하여 애플리케이션의 모듈화와 유지보수를 쉽게 함. 특히, Spring은 애플리케이션의 구성 요소 간 결합도를 낮추고, 확장성을 높여주는 경량 프레임워크로 자주 언급됨.
제어의 역전(IoC)은 객체 생성과 관리를 개발자가 아닌 Spring 컨테이너가 담당하는 개념임. IoC는 의존성 주입(DI) 패턴을 기반으로 동작하며, 객체 간의 의존성을 코드에서 직접 설정하지 않고, Spring이 필요한 객체를 주입해줌.
객체가 다른 객체와 협력할 때 필요한 의존 객체를 외부에서 주입받는 방식임. DI는 생성자 주입(Constructor Injection), 수정자 주입(Setter Injection), 필드 주입(Field Injection)의 세 가지 방식으로 제공됨.
@service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService (UserRepository userRepository) { // 의존성 주입
this.userRepository = userRepository;
}
}
@service
public class UserService {
private final UserRepository userRepository;
@Autowired
public setUserService (UserRepository userRepository) {
this.userRepository = userRepository;
}
}
@service
public class UserService {
@Autowired
private final UserRepository userRepository;
}
public class UserService {
private final UserRepository userRepository;
// 생성자 주입을 통해 의존성 주입
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
// 의존성은 final로 선언되어 객체 생성 후 변경되지 않음
}
// 생성자 주입을 통해 의존성을 강제
public class OrderService {
private final PaymentService paymentService;
public OrderService(PaymentService paymentService) {
if (paymentService == null) {
throw new IllegalArgumentException("PaymentService cannot be null");
}
this.paymentService = paymentService;
}
// OrderService는 PaymentService가 반드시 필요함
}
세터 주입이나 필드 주입의 경우, 테스트 중에 별도의 주입 방식이 필요하거나, 리플렉션(reflection)을 사용해야 할 수도 있지만, 생성자 주입은 간단히 생성자 호출을 통해 의존성을 주입할 수 있음.
생성자 주입 덕분에 테스트 환경에서 의존성 주입이 매우 단순해짐. 이를 통해 테스트 코드를 더 직관적이고 읽기 쉽게 작성할 수 있음.
public class ClassA {
private final ClassB classB;
public ClassA(ClassB classB) {
this.classB = classB;
}
}
public class ClassB {
private final ClassA classA;
public ClassB(ClassA classA) {
this.classA = classA;
}
}
의존성 숨김
테스트 어려움
순환 의존성 감지 불가
필드 주입은 구조가 불명확하고, 코드의 명확성을 떨어뜨리기 때문에 생성자 주입이 더 권장됨.
AOP는 프로그램의 비즈니스 로직과 이를 지원하는 횡단 관심사(Cross-Cutting Concerns)를 분리하는 기법임. 횡단 관심사는 여러 모듈에 걸쳐 공통으로 필요한 로직(예: 로깅, 보안, 트랜잭션 관리)인데, AOP는 이런 공통된 로직을 핵심 비즈니스 로직과 분리하여 코드 중복을 줄이고 유지보수를 쉽게 함.
POJO는 자바 객체가 특정 프레임워크나 기술에 종속되지 않고, 순수한 자바 객체로 개발할 수 있음을 의미함. Spring은 개발자가 특정 기술이나 프레임워크에 종속되지 않도록 POJO를 기반으로 애플리케이션을 구성할 수 있게 지원함. 즉, 애플리케이션 코드를 간결하고 유지보수 가능하게 만듦.
Spring은 모듈화된 구조를 가지고 있어 필요한 기능을 선택적으로 사용할 수 있음. 이 모듈들은 각각 특정 기능을 담당하며, Spring Core, Spring AOP, Spring MVC, Spring Data, Spring Security 등이 있음.
Spring의 핵심 모듈로, IoC(제어의 역전)와 DI(의존성 주입) 기능을 제공함. BeanFactory와 ApplicationContext 인터페이스를 통해 애플리케이션에서 사용하는 객체(빈)를 관리하고, 이 객체들 간의 의존성을 설정하고 주입함.
ApplicationContext는 Spring의 컨테이너로, 빈의 생성, 라이프사이클 관리, 의존성 주입 등을 담당함. 이를 통해 객체 간의 결합도를 낮추고 재사용성을 높임.
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService(userRepository());
}
@Bean
public UserRepository userRepository() {
return new UserRepository();
}
}
AOP 모듈은 애플리케이션의 횡단 관심사(예: 로깅, 보안, 트랜잭션 관리)를 비즈니스 로직과 분리하여 모듈화함. 이를 통해 코드 중복을 줄이고 비즈니스 로직을 깔끔하게 유지할 수 있음.
Aspect: AOP에서 공통 기능을 분리한 모듈.
Advice: 특정 시점(메소드 실행 전/후 등)에 실행될 코드.
@Aspect
@Component
public class TransactionAspect {
@Before("execution(* com.example.service.*.*(..))")
public void startTransaction() {
System.out.println("Start transaction...");
}
}
Spring MVC는 웹 애플리케이션 개발을 위한 Model-View-Controller 패턴을 구현한 모듈로, 클라이언트 요청을 처리하고, 응답을 제공하는 역할을 함. Spring MVC는 REST API 개발에도 자주 사용됨.
DispatcherServlet이 모든 요청을 받아 컨트롤러로 전달하며, 컨트롤러는 비즈니스 로직을 처리한 후, 결과를 뷰(View)에 전달하여 최종 HTML을 생성함.
@Controller
public class UserController {
@GetMapping("/users")
public String getUsers(Model model) {
List<User> users = userService.getUsers();
model.addAttribute("users", users);
return "userList";
}
}
Model: 애플리케이션의 데이터(비즈니스 로직에서 처리된 결과).
View: 사용자에게 보여줄 출력(HTML, JSON 등).
Controller: 클라이언트 요청을 처리하고, 적절한 응답을 반환하는 역할을 함.
Spring Data는 데이터베이스와의 연동을 단순화하는 모듈임. JPA, JDBC, MongoDB 등 다양한 데이터 소스와 연동을 지원하며, 데이터베이스와 상호작용하는 복잡한 코드를 자동으로 처리함.
Spring Data JPA를 사용하면 CRUD 작업을 자동으로 처리하는 리포지토리 인터페이스를 쉽게 정의할 수 있음.
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
Spring Data는 개발자가 SQL 쿼리나 데이터베이스 상호작용에 신경 쓰지 않고 비즈니스 로직에 집중할 수 있도록 도와줌.
Spring Security는 애플리케이션의 보안을 관리하는 모듈로, 인증(Authentication)과 인가(Authorization)를 지원함. 사용자의 인증 상태를 확인하고, 특정 권한이 있는 사용자만 접근할 수 있도록 설정할 수 있음.
Spring Security는 세션 관리, 암호화, OAuth, JWT(Json Web Token) 기반 인증 등을 지원함.
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
/* requestMathcers 해당 url로 요청될시
* permitAll 모두 허용
* hasRole 1개의 사용자만 허용
* hasAnyRole 명시된 사용자 모두 허용
* anyRequest requestMatchers에 해당되지 않는 모든 uri 가장 마지막에 설정 되어야함
* */
http.authorizeHttpRequests((auth) -> auth
.requestMatchers("/login","/","/join").permitAll()
.requestMatchers("/manager").hasAnyRole("MANAGER")
.requestMatchers("/admin").hasAnyRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
}
Spring Boot는 Spring Framework의 설정과 배포를 간소화한 확장 프레임워크임. Spring Boot는 자동 구성을 지원하여 복잡한 XML 설정 파일 없이 애플리케이션을 빠르게 개발하고 실행할 수 있게 해줌.
내장 웹 서버(예: Tomcat)를 제공하여 별도의 외부 서버 없이 애플리케이션을 독립적으로 실행할 수 있음.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Spring Cloud는 마이크로서비스 아키텍처를 지원하는 모듈로 서비스 등록/발견, 분산 트랜잭션, API Gateway 등의 기능을 제공함.
마이크로서비스 간의 상호작용을 관리하고, 서비스의 확장성을 높이는 데 도움이 됨.
Spring Framework는 자바 기반의 유연한 아키텍처와 다양한 모듈을 통해 엔터프라이즈 애플리케이션 개발에 최적화된 프레임워크임. Spring의 IoC, AOP, 의존성 주입과 같은 핵심 개념은 애플리케이션의 복잡성을 낮추고 확장성과 유지보수성을 높여줌. Spring Boot와 결합하여 애플리케이션 개발을 빠르고 효율적으로 할 수 있으며 마이크로서비스, 데이터베이스 연동, 보안 등 다양한 기능을 지원함.