Study/Lotte Study

Spring web MVC

명주_^ 2022. 7. 4. 21:33

<< 목차 >>

Part. 스프링 개발 환경 구축 
1. 개발환경 설정 
2. 스프링 프로젝트 생성 
3. Tomcat을 이용한 프로젝트 실행 확인 
4. Lombok 라이브러리 설치 
5. Java Configuration을 하는 경우 
6. 스프링의 특징(DI, AOP, IoC 등), 장점
7. 스프링 db 연동(mybatis) - mysql
8. 스프링 MVC 패턴 mvc1, mvc2
9. 스프링 MVC의 Controller,Service,Dao,Xml 화면 JSP -> 게시판  (CRUD)

 

1. 개발환경 설정

library 설치

2. 스프링 프로젝트 생성 

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
}

 

※ home.jsp 를 실행하게 되면 404 에러 발생.
→ 왜? WEB-INF는 보안의 이유때문에 직접 접근이 불가능하다. DB 정보도 저장이 되고 환경 설정을 위한 중요한 파일들이 존재하기 때문에. 프로젝트 자체를 실행!


3. Tomcat을 이용한 프로젝트 실행 확인 

프로젝트 실행


4. Lombok 라이브러리 설치 

Lombok?

public class HumanDto {
	
	private String name;
	private String team;
	private int age;
	private int num;
	private double height;
	private String area;
	private String address;
	private String hobby;
    
	public HumanDto(String name, String team, int age, int num, double height, String area, String address,
			String hobby) {
		super();
		this.name = name;
		this.team = team;
		this.age = age;
		this.num = num;
		this.height = height;
		this.area = area;
		this.address = address;
		this.hobby = hobby;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getTeam() {
		return team;
	}
	public void setTeam(String team) {
		this.team = team;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public double getHeight() {
		return height;
	}
	public void setHeight(double height) {
		this.height = height;
	}
	public String getArea() {
		return area;
	}
	public void setArea(String area) {
		this.area = area;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getHobby() {
		return hobby;
	}
	public void setHobby(String hobby) {
		this.hobby = hobby;
	}
}

↑ Lombok 사용하지 않는 경우

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@AllArgsConstructor
@Data
@Setter
@Getter
public class HumanDto {
	
	private String name;
	private String team;
	private int age;
	private int num;
	private double height;
	private String area;
	private String address;
	private String hobby;

}

Lombok 사용!

장점

  • annotation 기반의 코드 자동 생성을 통한 생산성 향상
  • 반복되는 코드 다이어트를 통한 가독성 및 유지보수성 향상
  • getter, setter 외에 패턴이나 로그 생성 등 활용 가능성

 

종류

  • @Getter, @Setter
  • @AllargsConstructor : 모든 변수를 사용하는 생성자
  • @NoArgsConstructor : 변수를 사용하지 않는 빈 생성자
  • @RequiredArgsConstructor : 특정 변수만을 활용하는 생성자
  • @EqualsAndHashCode : 클래스에 대한 equals 함수와 hashcode 함수를 자동으로 생성. 만약 서로 다른 두 객체에서 변수 이름이 같은 경우 같은 객체로 판단하고자 할 때 사용한다.
@EqualsAndHashCode(of = {"companyName", "industryTypeCode"}, callSuper = false))

 

서로 다른 두 객체가 companyName과 industryTypeCode 가 같다면 같은 객체로 인식. callSuper = false은 상속받은 상위 클래스의 경우 적용시키지 않음을 의미한다.

  • @ToString : ToString 메소드를 자동완성
    출력을 원하지 않는 메소드에 @ToString.Exlude 를 사용하면 출력에서 제외될 수 있다.
    @ToString(callSuper=true) 면 상위클래스에 대해 toString을 적용할 수 있게된다.
  • @Data : @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor을 자동완성
  • @Builder : 해당클래스의 객체의 생성에 Builder 패턴을 적용시켜준다. 생성자 인자가 많을 때 사용된다. 각 인자가 어떤 의미인지 쉽게 알 수 있는 장점이 있다.
Store store = Store.builder()
                .companyName("회사이름")
                .industryTypeCode("업종코드")
                .build();

 

5. Java Configuration을 하는 경우 

@Configuration 설정파일 생성하기

@Configuration이라는 어노테이션을 이용해서 해당 클래스의 인스턴스를 이용해서 설정파일을 대신할 수 있다.

도메인 패키지 하위경로에 config 패키지를 생성, RootConfig 클래스와 WebConfig, ServletConfig 클래스를 작성한다.

package com.happynarae.itapp.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages= {"com.[패키지경로]"})
public class RootConfig {

}

 


6. 스프링의 특징(DI, AOP, IoC 등), 장점

IoC(Inversion of Control)

- 제어의 역전. Spring에서의 Container를 의미한다. 컨테이너는 Bean의 생성부터 소멸까지 모든 생명주기를 관리한다. 컨트롤의 제어권이 개발자에게 있는게 아니라 프레임워크에 있는 것이다. Controller가 개발자를 대신하여 메소드가 호출될 때를 관리하고 메소드가 필요한 자원을 알아서 전달해주고 실행한다.

@Autoweird

 

DI(Dependency Injection)

- 의존관계 주입기능. 객체를 직접 생성하는 것이 아니라 외부에서 생성한 후 주입시켜주는 방식. DI를 통해 모듈간의 결합도가 낮아지고 유연성이 높아진다. IoC에서 컨테이너에서 Bean 객체를 생성하는 방식을 말한다. 객체를 직접 생성 또는 제어하는 것이 아니라 특정 객체가 필요하다면 객체를 외부에서 가져다가 주입하는 방식. 객체 생성을 하지 않으므로 new 연산자가 사라진다. Singleton 패턴.

※ Singleton pattern

public class Singleton {

    private static Singleton instance = new Singleton();
    
    private Singleton() {
        // 생성자는 외부에서 호출못하게 private 으로 지정해야 한다.
    }

    public static Singleton getInstance() {
        return instance;
    }

    public void say() {
        System.out.println("hi, there");
    }
}

객체의 인스턴스가 오직 1개만 생성되는 패턴

장점

  • 한번의 new 연산자로 고정된 메모리 영역을 사용하여 메모리 낭비를 방지할 수 있다
  • 이미 생성된 인스턴스를 활용하여 속도가 빠르다

단점

  • 코드가 어렵다
  • 테스트하기 어렵다

 

AOP(Aspect Oriented Programming)

- 관점지향 프로그래밍. 여러 메소드에서 공통적으로 코드가 중복된다면 공통 코드를 묶어 관리한다. interface를 사용하고 구현하는 것을 의미하기도 한다. 스프링에서의 AOP는 프록시 기반의 구현체이다. 프록시 객체를 사용하는 이유는 기존 코드의 변경 없이 접근 제어 및 부가기능을 추가하기 위함이다. 

※ Proxy pattern

proxy pattern

어떤 객체를 사용하고자 할 때, 객체를 직접적으로 참조하는 것이 아닌 해당 객체를 대항하는 객체를 통해 대상 객체에 접근하는 방식을 사용하면 해당 객체가 메모리에 존재하지 않아도 기본적인 정보를 참조하거나 설정할 수 있고 실제 객체의 기능이 필요한 시점까지 객체의 생성을 미룰 수 있다. 

공통된 처리 Logging, Transaction, session 처리

 

장점

  • 실제 객체의 메소드를 숨기고 인터페이스를 통해 노출할 수 있다.
  • 로컬에 있지 않고 떨어져 있는 객체를 사용할 수 있다.

단점

  • 객체 생성시 한 단계 거치므로 빈번한 객체 생성이 필요한 경우, 동기화가 필요한 경우 성능이 저하될 수 있다.
  • 로직이 난해해져 가독성이 떨어질 수 있다.

 

POJO ( Plain Old Java Object )

Getter/Setter를 가진 java Object를 사용할 수 있다.  

 


7. 스프링 db 연동(mybatis) - mysql

mysql에 연결된 db 값

 


8. 스프링 MVC 패턴 mvc1, mvc2

mvc1

JSP 모델. 웹 브라우저의 요청을 JSP 페이지가 받아서 처리한다. JSP 페이지에서는 로직 처리 코드와 웹 브라우저에 결과를 보여주기 위한 출력 코드가 함께 섞여있다. 모든 정보를 출력(view)하고 저장(model)하고 처리(control) 하므로 재사용이 힘들고 가독성이 떨어진다.

mvc2

Controller와 View를 분리한 형태. 웹 브라우저 요청을 하나의 서블릿이 받는다. 서블릿은 웹 브라우저 요청을 처리한 후 view에 넘기게 된다. 유지보수가 용이하다.

 

spring mvc

  • DispatcherServlet : 클라이언트의 요청을 전달받아 요청에 맞는 컨트롤러가 리턴한 결과값을 View에 전달.
  • HandlerMapping : 클라이언트의 요청 URL을 어떤 컨트롤러가 처리할지 결정
  • Controller : 클라이언트의 요청을 처리한 뒤, 결과를 DispatcherServlet에게 리턴
  • ViewResolver : 컨트롤러의 처리 결과를 생성할 뷰를 결정
  • View : 컨트롤러의 처리 결과 화면을 생성.

 

9. 스프링 MVC의 Controller,Service,Dao,Xml 화면 JSP -> 게시판  (CRUD)

9. HomeController 

(1) 프로젝트 실행하면 web.xml 실행 후 servlet-context로 전달된다

(2) servlet-context에서 annotation 사용여부 및 위치 확인 후 값을 전달한다

(3) HomeController에서 @Controller를 확인하여 mapping값인 "/"인 home 메소드가 실행된다.

(4) servlet-context.xml이 home에 preffix와 suffix를 붙여준다.

(5) home.jsp 실행된다!

 

[출처]

https://chanhuiseok.github.io/posts/spring-3/

 

[Spring] Spring의 MVC 패턴과 MVC1과 MVC2 비교

컴퓨터/IT/알고리즘 정리 블로그

chanhuiseok.github.io