Spring

Spring은 Java 기반의 현대적인 엔터프라이즈 애플리케이션 개발을 위한 포괄적인 프레임워크.

Spring은 웹 프레임워크가 아닌 일반 프레임워크.
그 이유는:

  1. 범위의 차이
  1. 기능의 포괄성
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// Spring으로 웹이 아닌 일반 애플리케이션도 개발 가능
@SpringBootApplication
public class BatchProcessingApplication {
    @Scheduled(fixedRate = 1000)
    public void processData() {
        // 배치 처리 로직
    }
}

// 데스크톱 애플리케이션도 가능
@SpringBootApplication
public class DesktopApplication extends Application {
    @Override
    public void start(Stage stage) {
        // JavaFX UI 로직
    }
}
  1. 모듈성
    Spring은 필요한 기능만 선택적으로 사용할 수 있다:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 웹 기능 없이 핵심 기능만 사용
@Configuration
@ComponentScan
public class CoreApplication {
    public static void main(String[] args) {
        ApplicationContext context = 
            new AnnotationConfigApplicationContext(CoreApplication.class);
        // 비즈니스 로직 실행
    }
}

특징:

  1. 의존성 주입(Dependency Injection, DI)
    Spring의 핵심 기능 중 하나로, 객체 간의 의존성을 외부에서 주입함으로써 결합도를 낮추고 유연성을 높인다.
    이를 통해 애플리케이션의 구조가 더욱 모듈화되고 테스트하기 쉬워진다.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// IoC와 DI 예시
@Service
public class UserService {
    // UserRepository 의존성을 자동 주입
    private final UserRepository userRepository;
    
    @Autowired  // 생성자 주입
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public User createUser(String username, String email) {
        // 비즈니스 로직 구현
        User user = new User(username, email);
        return userRepository.save(user);
    }
}

@Repository
public class UserRepository {
    @PersistenceContext
    private EntityManager entityManager;
    
    public User save(User user) {
        entityManager.persist(user);
        return user;
    }
}
  1. 관점 지향 프로그래밍(Aspect-Oriented Programming, AOP)
    로깅, 보안, 트랜잭션 관리와 같은 횡단 관심사를 분리하여 모듈화할 수 있게 해준다.
    이는 코드의 재사용성을 높이고 핵심 비즈니스 로직에 집중할 수 있게 해준다.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// AOP를 이용한 로깅 예시
@Aspect
@Component
public class LoggingAspect {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Around("execution(* com.example.service.*.*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        
        Object result = joinPoint.proceed();
        
        long executionTime = System.currentTimeMillis() - start;
        logger.info(
            "{} executed in {} ms", 
            joinPoint.getSignature(), 
            executionTime
        );
        
        return result;
    }
}
  1. 모듈화된 아키텍처
    Spring은 약 20개의 모듈로 구성되어 있으며, 개발자는 필요한 모듈만 선택하여 사용할 수 있다.
    주요 모듈에는 다음과 같은 것들이 있다:
    • Core Container: 프레임워크의 기본적인 부분을 제공.
    • Web: 웹 애플리케이션 개발을 위한 기능을 제공.
    • Data Access/Integration: 데이터 접근과 통합을 위한 기능을 제공.
    • Testing: 단위 테스트와 통합 테스트를 지원.

장점:

  1. POJO 기반: 특별한 인터페이스를 구현하거나 클래스를 상속받을 필요 없이 일반 Java 객체를 사용할 수 있다.
  2. 경량 컨테이너: 무거운 엔터프라이즈 컨테이너 없이도 애플리케이션을 개발할 수 있다.
  3. 유연한 설정: XML 기반 설정과 Java 기반 어노테이션 설정을 모두 지원한다.
  4. 테스트 용이성: 의존성 주입을 통해 단위 테스트가 쉬워진다.
  5. 트랜잭션 관리: 일관된 트랜잭션 관리 인터페이스를 제공한다.

Spring의 아키텍처:
Spring은 일반적으로 세 가지 주요 계층으로 구성된다.

  1. 프레젠테이션 계층: 사용자 인터페이스를 처리한다.
  2. 비즈니스 로직 계층: 애플리케이션의 핵심 기능을 구현한다.
  3. 데이터 접근 계층: 데이터베이스와의 상호작용을 관리한다.

Spring의 주요 프로젝트

Spring Boot

빠른 애플리케이션 개발을 위한 도구로, 최소한의 설정으로 독립적으로 실행 가능한 프로덕션 수준의 Spring 기반 애플리케이션을 쉽게 만들 수 있게 해준다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
@SpringBootApplication
public class MyApplication {
 public static void main(String[] args) {
  SpringApplication.run(MyApplication.class, args);
 }
}

// 애플리케이션 설정
// application.properties 또는 application.yml
spring:
  datasource:
 url: jdbc:postgresql://localhost:5432/mydb
 username: user
 password: password
  jpa:
 hibernate:
   ddl-auto: update
  server:
 port: 8080
역할

Spring Boot는 Spring Framework를 더 쉽게 사용할 수 있게 해주는 도구입니다:

  1. 자동 설정 제공
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// Spring Boot 없이 설정할 경우
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
    // 더 많은 설정들…
}

// Spring Boot 사용 시
// application.properties에 간단히 설정
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
  1. 내장 서버 제공
1
2
3
4
5
6
7
8
// Spring Boot는 내장 톰캣을 포함
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        // 이 한 줄로 웹 서버 시작
        SpringApplication.run(Application.class, args);
    }
}
  1. 의존성 관리 단순화
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- Spring Boot 사용 전 -->
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.3.9</version>
    </dependency>
    <!-- 수많은 다른 의존성들… -->
</dependencies>

<!-- Spring Boot 사용 후 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.4</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

Spring Data

다양한 데이터 저장소에 대한 통합된 데이터 접근 API를 제공한다.
JPA, MongoDB, Redis 등 다양한 데이터베이스를 지원한다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Entity  
public class User {  
 @Id  
 @GeneratedValue(strategy = GenerationType.IDENTITY)  
 private Long id;
 
 private String username;
 private String email;
 
 @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
 private List<Order> orders = new ArrayList<>();
}

// Repository 인터페이스
public interface UserRepository extends JpaRepository<User, Long> {
 // 메서드 이름으로 쿼리 생성
 Optional<User> findByEmail(String email);
 
 // 커스텀 쿼리
 @Query("SELECT u FROM User u WHERE u.username LIKE %:keyword%")
 List<User> searchByUsername(@Param("keyword") String keyword);
}

Spring Security

인증과 권한 부여를 위한 포괄적인 보안 서비스를 제공한다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
 
 @Override
 protected void configure(HttpSecurity http) throws Exception {
  http
   .authorizeRequests()
    .antMatchers("/public/**").permitAll()
    .antMatchers("/api/**").authenticated()
    .anyRequest().authenticated()
   .and()
   .formLogin()
    .loginPage("/login")
    .permitAll()
   .and()
   .oauth2Login()
    .loginPage("/login")
   .and()
   .csrf()
    .ignoringAntMatchers("/api/**");
 }
}

참고 및 출처

Spring | Home