(TIL) 4/14 Spring Framework

IT_JANG·2025년 4월 15일
  • 정의
    • 자바 플랫폼을 위한 오픈 소스 애플리케이션 프레임워크
    • 동적인 웹 사이트 개발 관련 서비스를 제공
    • 대한민국 공공기관의 웹 서비스 개발 시 사용을 권장하고 있는
      전자정부 표준 프레임워크(Spring MVC Project 기반 프레임워크)의 기반 기술로서 사용
  • 종류
    • Spring MVC : 수동, 업데이트 없음
    • Spring Boot : 자동
  • 특징
    • IOC (Inversion of Control : 제어 반전)
      • 정의
        • 컨트롤의 제어권이 개발자가 아니라 프레임워크에 있음
        • 객체의 생성부터 모든 생명주기의 관리까지 프레임워크가 주도
        • 개발자 객체 생성 X, 직접 호출 X : new 사용 X
          Spring Container가 만들어둔 객체(Bean) 얻어와서 사용
        • 클래스간의 결합도를 낮추고 유지보수성을 향상시킬 수 있음
      • 어노테이션 Component Scan(Bean Scanning)
        어노테이션설명
        @Component객체(컴포넌트)를 나타내는 일반적인 타입으로 <bean> 태그와 동일한 역할
        @Repository퍼시스턴스(persistence) 레이어, 영속성을 가지는 속성(파일, DB)을 가진 클래스
        ex) Data Access Object Class
        @Service서비스 레이어, 비즈니스 로직을 가진 클래스
        ex) Service Class
        @Controller프레젠테이션 레이어, 웹 애플리케이션에서 View에 전달될 웹 요청과 응답을 처리하는 클래스
        ex) Controller Class
    • DI (Dependency Injection : 의존성 주입)
      • 정의
        • 설정 파일(XML)이나 어노테이션을 통해 객체 간의 의존 관계를 설정하여
          개발자가 직접 객체를 생성하지 않고 Spring Container가 만들어둔 객체를 필요한 위치에서 주입
        • (직접 객체를 만들지 않고 Spring이 만든 객체를 얻어와 사용 == 의존)
      • 어노테이션
        어노테이션설명
        @Autowired- 정밀한 의존 관계 주입(DI)이 필요한 경우 사용
        • 필드, setter, 생성자, 일반 메서드에 적용 가능
        • 주로 Type 기준으로 의존 객체를 자동 주입
        • <property>, <constructor-arg>와 동일한 역할 |
          | @Qualifier | - @Autowired와 함께 사용
        • 주입 대상 객체가 여러 개일 때, @Qualifier("이름")로 특정 객체를 지정하여 주입 가능 |
    • POJO(Plain Old Java Object : 일반 올드 자바 객체)
      • J2EE, EJB와 같은 특정 기술이나 라이브러리의 내용을 상속 받아 클래스를 구현하지
        않고, 일반적인 자바 객체(POJO)를 사용할 수 있도록 지원함
      • 프레임워크 학습 곡선을 낮추고 코드의 가독성을 높일 수 있음
      • J2EE(Java2 Enterprise Edition) : Servlet, JSP 레벨의 서버 프로그래밍 인터페이스
      • EJB(Enterprise Java Bean) : 쉽게 웹 개발이 가능한 기술, 객체지향 장점을 포기해야 하는
        문제점 발생
    • AOP (Aspect Oriented Programming : 관점 지향 프로그래밍)
      • 로깅, 보안, 트랜잭션 관리 등 공통적인 관심사를 분리
      • 코드 중복 감소, 유지보수성 향상 시키는 기능 지원
    • Spring MVC
      • MVC(Model, View, Controller) 디자인 패턴을 적용할 수 있는 어노테이션을 지원
      • IOC / DI를 이용해 의존 관계를 관리하여 개발자가 아닌 서버가 객체들을 관리하는 웹 애플리케이션을 구축 할 수 있음
    • PSA (Portable Service Abstraction : 휴대용 서비스 추상화)
      • 다른 여러 모듈을 사용함에 있어 별도의 추상화 레이어를 제공하여 특정 기술에 종속되지 않으면서 다양한 기술 스택을 쉽게 사용할 수 있음
      • (외부 라이브러리, API 등 외부 기술을 쉽게 이용할 수 있도록 여러 인터페이스, 추상 클래스를 제공)
  • Spring Container 구성 모듈(기본 구성) image.png
    • Data 접근 계층
      • JDBC나 데이터베이스에 연결하는 모듈로, Data 트랜잭션에 해당하는 기능을 담당하여
        영속성 프레임워크의 연결을 담당
    • Web 계층 (MVC / Remoting)
      • Spring Framework에서 Servlet등의 웹 구현 기술과의 연결점을 Spring MVC 구성으로 지원하기 위해 제공되는 모듈 계층
      • 스프링의 리모팅 기술로 RMI, Hessian, Burlap, JAX-WS, HTTP 호출자 그리고 REST API 모듈을 제공
    • AOP 계층
      • Spring에서 각 흐름 간 공통된 코드를 한 쪽으로 빼내어 필요한 시점에 해당 코드를 첨부하게 하기 위해 지원하는 계층으로, 별도의 proxy를 두어 동작
      • 이를 통해 객체간의 결합도를 낮출 수 있음
    • Core Container
      • Spring의 핵심 부분 모든 스프링 관련 모듈은 이 Core Container 기반으로 구축됨
      • Spring의 근간이 되는 IOC 기능을 지원하는 영역을 담당
      • BeanFactory를 기반으로 Bean 클래스들을 제어할 수 있는 기능을 지원
  • Spring MVC 요청 처리 과정 image.png
    구성 요소설명
    DispatcherServlet클라이언트 요청을 받아 적절한 컨트롤러에 전달하고, 컨트롤러의 처리 결과를 View에 전달하여 응답 생성
    HandlerMapping요청 URL에 따라 어떤 컨트롤러가 처리할지 결정
    Controller클라이언트 요청을 실제로 처리하고 결과를 DispatcherServlet에 반환
    ModelAndView컨트롤러가 반환하는 객체로, 처리 결과 데이터(Model)와 뷰(View) 정보를 함께 포함
    ViewResolverModelAndView의 View 이름을 기반으로 실제 View(JSP 등)를 결정
    View최종적으로 사용자에게 보여질 화면을 생성 (JSP, Thymeleaf, Velocity 등)
  • 프로젝트 구조 image.png
    • src/main/java : 자바 소스 코드를 모아두는 폴더
      • 파일이름Application.java : 프로젝트 생성 시 자동 생성
        ㄴ main 메서드가 존재 -> 실행 -> 내장된 Tomcat 서버가 배포를 시작
    • src/main/resources : 자바에서 사용할 자원, 설정 파일을 모아두는 폴더
      • templates : Java 템플릿을 모아두는 폴더 (Thymeleaf)
      • static : templates에 적용될 정적 자원을 모아두는 폴더 (JS, CSS, 이미지)
      • application.properties : Spring Boot 프로젝트 관련 설정을 정의하는 파일 (중요)
    • Project and External Dependencies : build.gradle에 명시된 라이브러리 모음
    • build.gradle
      • Gradle 빌드 도구를 사용하는 프로젝트에서 빌드 설정을 정의하는 파일
  • 프로젝트 설정
    • application.properties
      # 해당 파일에 설정 작성 시 프로젝트 전반적으로 설정이 적용됨
      
      #애플리케이션(프로그램) 이름
      spring.application.name=demoProject1
      
      # port번호 80으로 변경(80은 HTTP의 기본 포트번호로, 브라우저에서 포트번호 없이 접속 가능)
      server.port=80
      
      # Spring DevTools (자동 리로드 서버 재시작) 설정
      
      # 브라우저 자동 새로 고침 기능
      spring.devtools.livereload.enabled=true
      
      # 코드 변경 시 서버 자동 재시작
      spring.devtools.restart.enabled=true
      
      # 타임리프 캐시 비활성화 (HTML 파일 수정 시 바로 변경사항 확인할 수 있도록)
      spring.thymeleaf.cache=false
      
      # 로그 레벨 지정
      logging.level.edu.kh.demo=debug
      
      # 로그레벨 6단계
      # TRACE : 가장 상세한 로그레벨로, 상세한 정보를 기록
      # DEBUG : 디버깅에 유용한 정보를 기록(값 추적)
      # INFO 	: 일반적인 정보 메시지 기록 ( Spring boot에서 자동으로 기본 레벨 INFO)
      # WARN 	: 경고 메시지를 기록
      # ERROR : 오류 메시지를 기록, 심각한 문제 발생 시 사용
      # FATAL : 가장 심각한 오류, 프로그램 실행 중단의 치명적 오류 기록
      
    • build.gradle
      • 정의
        • Gradle 빌드 도구를 사용하는 프로젝트에서 빌드 설정을 정의하는 파일
      • 주의사항
        • 괄호 안 부분 수정 시 저장 후
          프로젝트 우클릭 -> Gradle -> Refresh Gradle Project 클릭
      • 사용법
        • dependencies{} : 외부 연결된 사이트 (MVNrepository)
          • 작성된 모듈, 라이브러리를 다운로드 받아서 프로젝트에 자동으로 추가
          • https://mvnrepository.com/에서 필요한 사항 찾아서 gradle문으로 추가
      • 형태
        plugins {
        	id 'java'
        	id 'org.springframework.boot' version '3.4.4'
        	id 'io.spring.dependency-management' version '1.1.7'
        }
        
        group = 'edu.kh'
        version = '0.0.1-SNAPSHOT'
        
        java {
        	toolchain {
        		languageVersion = JavaLanguageVersion.of(21)
        	}
        }
        
        configurations {
        	compileOnly {
        		extendsFrom annotationProcessor
        	}
        }
        
        repositories {
        	mavenCentral()
        }
        
        // 외부 연결된 사이트 (MVNrepository)
        // 아래에 작성된 모듈, 라이브러리를 다운로드 받아서 프로젝트에 자동으로 추가
        // 아래 dependencies 괄호 안 부분 수정 시 저장 후
        // 프로젝트 우클릭 -> Gradle -> Refresh Gradle Project 클릭
        
        dependencies {
        	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
        	implementation 'org.springframework.boot:spring-boot-starter-web'
        	compileOnly 'org.projectlombok:lombok'
        	developmentOnly 'org.springframework.boot:spring-boot-devtools'
        	annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
        	annotationProcessor 'org.projectlombok:lombok'
        	testImplementation 'org.springframework.boot:spring-boot-starter-test'
        	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
        }
        
        tasks.named('test') {
        	useJUnitPlatform()
        }
        
  • 주소 경로
    		/*
    		 * Controller 메서드의 반환형이 String인 이유
    		 * -> 메서드에서 반환되는 문자열이
    		 * 	  forward할 html 파일의 경로가 되기 때문
    		 * 
    		 * Thymeleaf : JSP 대신 사용하는 템플릿 엔진(html 형태)
    		 * 
    		 * classpath = sre/nain/resources
    		 * 접두사 : classpath:/templates/
    		 * 접미사 : .html
    		 * 
    		 */
    		
    		// src/main/resources/templates/test.html
    		return "test"; // 접두사 + 반환값 + 접미사 경로의 html로 forward
    
    	// - 공통 주소를 매핑
    	//  ex) /todo/insert, /todo/select, /todo/update ...	
    	@RequestMapping("/todo")
    	public class TestConstroller {
    		
    		@RequestMapping("/insert")
    		public String 메서드명() {}
    		
    		@RequestMapping("/insert")
    		public String 메서드명() {}
    		
    		@RequestMapping("/insert")
    		public String 메서드명() {}
    	}
    	
  • 어노테이션(@)
    • @SpringBootApplication
      • Spring Boot Application 필요한 필수 어노테이션과 설정을 모아둔 어노테이션
      • Application.java에 자동 작성
    • @Controller
      • 요청/응답 제어 + Bean 등록
    • @GetMapping("주소") : 요청 시 호출
      • 주소 앞 “/” 생략 : Spring에서는 잘 돌아감, AWS 사용시 리눅스 환경에서 build 오류
    • @PostMapping
    • @PutMapping
    • @DeleteMapping
    • @RequestMapping("주소")
      • 요청 주소를 처리할 메서드를 매핑하는 어노테이션

      • GET/POST 가리지 않고 매핑 -> (속성을 통해서 지정 가능 or 다른 어노테이션 이용)

        	@RequestMapping(value="test", method = RequestMethod.GET)
        	@RequestMapping("test") // /test 요청 시 testMethod가 매핑하여 처리함
    • @Slf4j : log.debug() 사용 가능 (Lombok 기능)
      • log를 이용한 메시지 콘솔창에 출력할 때 사용(Lombok 제공)

        @Slf4j
        public class logTest(){
        	log.debug("inputName : " + inputName);
        }

0개의 댓글