JAVA Spring #2

keymu·2024년 11월 11일
0

자동 주입이 발생될 수 있는 3가지 위치

  1. Constructor injection (생성자)
  2. Field injection (멤버변수)
  3. Setter injection (setter)

Java Spring DI의 대표적 규칙

규칙 1. 생성자가 하나만 있는 경우 생성자 @Autowired 생략가능

Spring 4.3부터 그런 규칙이 적용된다.

규칙 2. Only one constructor can have @Autowired

No default Constuctor: 생성자가 여러 개 overloading 될 수 밖에 없게 @Autowired가 여러 생성자 중 어느 것에도 안 붙었을 경우

규칙 3. 동일한 타입의 bean이면, name이 같거나 (유사)한 것이 주입된다.

@Qualifer, @Primary 등으로 특정 이름의 bean 주입도 가능하다.
@Primary: 이렇게 정의된 애를 먼저 데려가세요, 하고 적어두는 것. 동일 타입의 bean이 여러 개 있을 때, 얘가 대표니까 데려가세요, 하는 것.

Field Injection은 최대한 비추합니다.

Stereotype

  • Container에 bean으로 생성하는 annotation들
  • Spring MVC에서 사용

@Component: 일반적인 bean
@Controller: Spring MVC에서 Controller로 사용
@Service: Service 단으로 사용
@Repository: DAO, Persistence로 사용

Inversion of Control을 활용해 스프링 컨테이너에서는 주입받는 객체가 먼저 생성되고, 의존하는 객체를 나중에 생성하여 주입한다.

DI 설정 시 순환 참조(dependency cycle) 발생하지 않도록 주의해야 한다.

@Value

부트설정파일 application.properties에 있는 value를 가져올 수 있다.
Lombok의 Value와 헷갈려서 import하면 안된다.

environment: 개발환경이냐, 프로덕션 환경이냐를 나눌 때 쓰게 되는 변수. Boot의 등장 이전에 많이 썼던 환경변수


Spring Web Application의 구조

MVC

M: Model - Data
V: View - 사용자와의 interaction
C: Controller - 사용자 입력 처리, 출력 과정 컨트롤

Model

  • Data를 실어나르는 객체, Business Logic 처리 결과를 담아서 View까지 전달
  • model.addAttribute(name, value): Model에 Data 담기

Controller

  • 어떠한 Request를 받음 -> business Logic 처리(Service 단에 위임) -> 어떤 Response할지 정의

@RequestMapping

  • @RequestMapping("/"): "/"라는 url로 request가 들어오면 아래 메소드가 처리(handle)
  • @RequestMapping("/aaa"): "/aaa"라는 url로 request가 들어오면 아래 메소드가 처리
  • static resource: Spring MVC는 기본적으로 resources/static folder를 static resource root 삼는다.
  • 똑같은 경로를 처리하는 handler가 있을 수 없다.
  • return "home" : String을 리턴하는 handler. view 리턴: ViewResolver를 통해 탬플릿 파일 찾아 template engine에 전달
  • home: "home.html"은 template file

ViewResolver

  1. view file(template)을 찾아낸다
  2. prefix + "home" + suffix
  3. template/views/ + "home" + ".html"
  4. ViewResolver가 선택한 "template file", "Model Data"는 설정된 Template Engine(Thymeleaf, Mustache)에 넘어간다.
  5. Template engine: Template file + Data -> response할 데이터 생성

@HttpServletRequest (request 객체)

  • request에 대한 정보는 HttpSevletRequest 객체를 통해 읽을 수 있다.
  • url, parameter, cookie, session, header
  • handler의 매개변수로 설정해두면 request 시 spring container가 전달해준다.

@ResponseBody

  • 자바 객체를 그대로 response(view 사용 없이)
  • String을 리턴하면 문자열 텍스트로 response
  • Java 객체를 리턴하면 JSON으로 response
  • List<>, Set<>, 배열 => JSON Array로 변환
  • Map<>, Java Object => JSON object로 변환 (Property 사용)

라우팅->request mapping

org.springframework.html package의 주요 객체

HttpEntity<T>
  • HTTP Request, 혹은 HTTP response 표현 객체
  • headers + body
  • request, response 보다 세밀하게 제어
  • T: response할 body의 타입
  • SpringMVC @Controller 메소드의 return값으로도 사용
  • RestTemplate에서도 활용
RequestEntity<T>
  • HTTP request 표현 객체
  • SpringMVC @Controller 메소드의 '입력값'
  • RestTemplate에서도 활용
ResponseEntity<T>
  • HTTP response 표현 객체
  • Status Code도 설정 가능
  • SpringMVC @Controller 메소드의 '리턴값'
  • RestTemplate에서도 활용
// HttpEntity<T> 리턴 : T 는 response 할 body 의 타입
@RequestMapping("http01")
@ResponseBody
public HttpEntity<String> http01() {
    String body = str1;
    HttpEntity<String> entity = new HttpEntity<>(body);   // HttpEntity(body)
    return entity;
    //  기본적으로 text/html;charset=UTF-8  로 response 된다.
}

// HttpHeaders : header 세팅 가능

@RequestMapping("http02")
@ResponseBody
public HttpEntity<String> http02() throws UnsupportedEncodingException {
    HttpHeaders headers = new HttpHeaders();
    //headers.setContentType(MediaType.TEXT_PLAIN);  // text/plain 으로 response
    headers.setContentType(new MediaType("text", "plain", Charset.forName("UTF-8")));
    //headers.add("Content-type", "text/plain;charset=utf-8");
    headers.add("user-secret", "xxxxx");
    //headers.add("my-team", "삼성라이온즈");  // 에러, 헤더 정보는 반드시 url encoding 되어야 한다.
    headers.add("my-team", URLEncoder.encode("삼성라이온즈", "utf-8"));

    String body = str1;
    HttpEntity<String> entity = new HttpEntity<>(body, headers);   // HttpEntity(body, headers)
    return entity;
}


// 일반적으로 response 로서 HttpEntity<T> 보다는 ResponseEntity<T> 사용
@RequestMapping("http03")
@ResponseBody
public ResponseEntity<String> http03() {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);  // "application/json"
    String body = jsonArr[0];

    ResponseEntity<String> entity;
    //entity = new ResponseEntity<>(body, headers, HttpStatus.OK);  // (body, header, response code)
    entity = ResponseEntity.ok().headers(headers).body(body);
    return entity;
}

// body 에는 어떠한 Java 객체도 가능
@RequestMapping("http04")
@ResponseBody
public ResponseEntity<HomeController1.Product> http04() {
    HomeController1.Product product = new HomeController1.Product(10, "자전거", false);
    return new ResponseEntity<>(product, HttpStatus.OK);

    // <T> 타입 명시하기 귀찮다.. 자주 바뀌기도 하고..
}

// type parameter 를 ? (혹은 Object) 로 작성해두면 편리하다 (일반적으로 많이 쓰임)
// ※ 개발단계에서 response body 의 타입은 유동적으로 변할수 있기 때문이다.
@RequestMapping("http05")
@ResponseBody
public ResponseEntity<?> http05() {
    var product = new HomeController1.Product(10, "자전거", false);
    return new ResponseEntity<>(product, HttpStatus.OK);  // (body, statusCode)
}

// 다양한 statusCode 값 명시하여  response 가능.
@RequestMapping("http06")
@ResponseBody
public ResponseEntity<?> http06() {
    return
            //new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
            //ResponseEntity.badRequest().build();
            new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}

ModelAndView 객체

  • View, Model(data)를 둘다 ModelAndView에 세팅
  • wildCard 사용 가능
(/member/action/*/*/**)
  • 확장자 패턴 사용 가능
(/member/*.do)

url의 구성 : /{controller}/{action}

@Controller
@RequestMapping("/member") // ← 이 컨트롤러는 "/member" 로 시작하는 url 에 매핑된다.
public class MemberController {

    @RequestMapping("/save")    // URL mapping →  /member + /save  =>  /member/save
    public String saveMember(){
        return "member/save";
    }

    @RequestMapping("/load")   //  /member + /load => /member/load
    public void loadMember(){
        // return "/member/load" 를 리턴한것과 동일
    }

//    @RequestMapping("/search")  //   /member/search
//    public void searchMember(){
//        // url mapping 중복 시, server 가동 시 죽음!
//    }
}
profile
Junior Backend Developer

0개의 댓글