Spring Project의 디렉토리 구조

CJI0524·2025년 3월 25일

Spring Boot

목록 보기
4/21

1. Spring 프로젝트의 디렉토리 구조

해당 게시글에서는 Spring 프로젝트의 디렉토리 구조와 각 디렉토리가 무엇을 의미하고 어떠한 파일들을 저장하는지에 대해 알아본다.

1.1. Domain/Model

  • 애플리케이션의 핵심 비즈니스 로직과 데이터를 표현하는 객체들이 모여 있음.
  • 예: Entity, VO, Domain 모델, 비즈니스 로직 클래스 등

✍️ 예제 코드 작성

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;

    // 생성자, getter, setter 생략

    // 비즈니스 로직 예시: 이메일 변경 메서드
    public void updateEmail(String newEmail) {
        // 검증 로직 등 추가 가능
        this.email = newEmail;
    }
}

1.2. Repository

  • 데이터베이스 등 외부 저장소와의 통신을 담당.
  • 예: Spring Data JPA의 JpaRepository, CrudRepository 등, 또는 직접 구현한 DAO

✍️ 예제 코드 작성

public interface UserRepository extends JpaRepository<User, Long> {
    // 추가적인 쿼리 메서드 선언 가능
    Optional<User> findByEmail(String email);
}

또는 다음과 같이 직접 DAO로 구현 가능.

✍️ 예제 코드 작성

@Repository
public class UserDAO {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public User findUserById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new Object[]{id}, (rs, rowNum) ->
            new User(rs.getLong("id"), rs.getString("name"), rs.getString("email"))
        );
    }
}

1.3. Service

  • 비즈니스 로직을 실제로 처리하는 계층.
  • Repository와 Domain을 활용해서 기능을 구현하고, 여러 컨트롤러에서 공통적으로 사용하는 로직을 캡슐화.

✍️ 예제 코드 작성

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public User getUser(Long id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new UserNotFoundException("사용자를 찾을 수 없습니다"));
    }

    public User registerUser(User user) {
        // 이메일 중복 체크 등 추가 로직 가능
        return userRepository.save(user);
    }
}

1.4. Controller

  • 클라이언트의 요청을 받고 Service를 호출해 응답을 만들어 내는 진입점.
  • @RestController나 @Controller로 사용하고, URL 매핑 등 요청 처리 로직을 포함.

✍️ 예제 코드 작성

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
        User user = userService.getUser(id);
        // 도메인 객체를 DTO로 변환해서 반환
        UserDTO dto = new UserDTO(user.getId(), user.getName(), user.getEmail());
        return ResponseEntity.ok(dto);
    }
}

1.5. DTO

  • 계층 간 (주로 Controller와 Service 사이) 데이터를 주고받을 때 사용하는 객체.
  • Entity와 달리 필요한 데이터만 전달할 수 있도록 별도로 관리.

✍️ 예제 코드 작성

public class UserDTO {
    private Long id;
    private String name;
    private String email;

    public UserDTO(Long id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
    // getter, setter 생략
}

1.6. Config

  • 애플리케이션 전반의 설정이나 Bean 등록, 외부 설정 파일 등을 관리하는 곳.
  • 예: DataSource, Security, WebMvc 설정 등

✍️ 예제 코드 작성

@Configuration
public class AppConfig {
    // 예: 빈(bean) 등록
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

1.7. View

  • 사용자에게 보여질 UI 관련 파일들이 모여 있음.
  • 예: Thymeleaf 템플릿, JSP, 정적 리소스 (CSS, JS, 이미지 등)

✍️ 예제 코드 작성

<!-- resources/templates/user.html (Thymeleaf 예제) -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>User Info</title>
</head>
<body>
    <h1 th:text="${user.name}">User Name</h1>
    <p th:text="${user.email}">User Email</p>
</body>
</html>

1.8. Exception

  • 커스텀 예외 처리 클래스나 글로벌 예외 처리(ControllerAdvice)를 관리.
  • 애플리케이션의 오류 상황을 구조화해서 다루기 좋게 만들어줌.

✍️ 예제 코드 작성

public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}

// 글로벌 예외 처리 예시
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<String> handleUserNotFound(UserNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }
}

1.9. Util/Helper

  • 여러 계층에서 공통으로 사용할 수 있는 유틸리티 함수나 상수, 헬퍼 클래스를 모아둠.
  • 예: 문자열 처리, 날짜 계산, 공통 상수 등

✍️ 예제 코드 작성

public class StringUtil {
    public static boolean isEmpty(String str) {
        return str == null || str.trim().isEmpty();
    }
}

1.10. Security, Aspect, Event, Batch 등

  • Security: 인증, 권한 등 보안 관련 설정 및 클래스
  • Aspect: AOP를 이용해 횡단 관심사 (로깅, 트랜잭션, 퍼포먼스 등)를 분리한 클래스
  • Event: 애플리케이션 이벤트를 발행하고 처리하는 클래스
  • Batch: 배치 작업, 스케줄링 관련 코드

✍️ 예제 코드 작성 (Security)

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
          .formLogin();
    }
}

✍️ 예제 코드 작성 (Aspect)

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void logBeforeMethod(JoinPoint joinPoint) {
        System.out.println("메서드 호출: " + joinPoint.getSignature().getName());
    }
}

1.11. Test

  • 유닛 테스트, 통합 테스트 코드가 위치하는 곳.

✍️ 예제 코드 작성

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void testGetUser() {
        User user = userService.getUser(1L);
        assertNotNull(user);
    }
}

2. 이 글을 작성하는데 참고한 글 목록

[Spring 게시판] 4. 기본 폴더 구조 정리1
Spring Guide - Directory

profile
개발돌이

0개의 댓글