diff --git a/kimjeakwan/java/20240520.md b/kimjeakwan/java/20240520.md new file mode 100644 index 0000000..6025136 --- /dev/null +++ b/kimjeakwan/java/20240520.md @@ -0,0 +1,112 @@ +# 자바의 optional +- 정의되지 않은 객체에 대해 NULL값을 고려하게 되는 경우가 발상핸다. 이떄 안정적인 실해을을 위해서는 NULL값을 처리해 NPE가 발생하지 않게 체크해야 한다. +- optional는 NULL이 올 수 있는 값을 감싸는 Wrapper 클래스로, NPE가 발생하지 않도록 도와준다. +- optional 클래스는 value에 값을 저장하기 떄문에 NULL이더라고 바로 NPE가 발생하지 않는다. +# optional 클래스 주요 메서드 +- empty() +> 기능: 비어있는 Optional 객체를 생성. +> 리턴값: Optional +- of(T value) +> 기능: 전달된 값으로 새로운 Optional 객체를 생성. +>리턴값: Optional +- ofNullable() +> 기능: 비어있을 수 있고, 아닐 수도 있는 Optional 객체를 생성. +>반환값: Optional +- equals(object obj) +> 기능: Optional 객체의 값을 비교. +> 리턴값: boolean +- filter(Predicate predicate) +>기능:Optional 객체의 값을 조건에 따라 필터링. +>리턴값:Optional +- map(Function mapper) +>기능:Optional 객체 내부의 값을 변환하여 결과를 새로운 Optional 객체로 반환. +> 일반적인 변환을 수행하여 Optional를 Optional로 변환합니다. +>리턴값: Optional +- flatMap(Function> mapper) +> 기능:중첩된 Optional +> Optional 객체의 값을 변환하고, 변환된 값이 Optional 객체인 경우에 사용됩니다. +>flatMap 메서드를 사용하면 중첩된 Optional 객체를 하나의 optional 객체로 변환하여 하나의 Optional 객체로 다룰 수 있다. +> 리턴값: Optional +- flatmap 과 map 의 차이점 +> map 매서들 사용하여 중첩된 구조를 만들수 있다. +> flatmap 매서드를 사용하여 중첩된 구조를 하나의 구조로 만든다. +- get() +> Optional 객체의 값을 가져온다. +(만약 값이 존재하지 않는 경우, NoSuchElementException이 발생) +- isEmpty +> Optional 객체가 비어있는지 확인 한다. +>Optional 객체에 값이 없는 경우 true를 반환하고, 값이 있는 경우 false를 반환한다. +- ispresent() +> optiomal 객체가 있는지 확인한다. +- ifpreseint(Consumer action) +> Optional 객체가 있다면 내부 연산을 실행한다. +- ifPresentOrElse() +> Optional 객체가 있다면 내부 연산을 실행, 없다면 또 다른 내부 연산을 실행 +```java +import java.util.Optional; + +public class IfPresentOrElseExample { + public static void main(String[] args) { + // 값이 있는 Optional 객체 생성 + Optional nonEmptyOptional = Optional.of("Hello, world!"); + + // 값이 없는 Optional 객체 생성 + Optional emptyOptional = Optional.empty(); + + // ifPresentOrElse 사용 + nonEmptyOptional.ifPresentOrElse( + value -> System.out.println("Value is present: " + value), + () -> System.out.println("Value is not present") + ); + + emptyOptional.ifPresentOrElse( + value -> System.out.println("Value is present: " + value), + () -> System.out.println("Value is not present") + ); + } +} +``` +- or() +> Optional 객체가 비어있다면, 다른 Optional 객체를 반환한다. +> or 메서드를 사용하면 코드를 더 간결하게 만들고, Optional 객체의 값 유무에 따라 적절한 동작을 수행할 수 있다. +```java +import java.util.Optional; + +public class OrExample { + public static void main(String[] args) { + Optional optional = Optional.empty(); + Optional result = optional.or(() -> Optional.of("Default Value")); + System.out.println("Result: " + result.orElse("No value")); + } +} +``` +- orElse +> Optional 객체가 비어있다면, 전달된 기본값 other를 반환. +- orElseGet +> Optional 객체가 비어있다면, 내부 함수를 실행하여 생성된 기본값을 반환. +```java +import java.util.Optional; + +public class OrElseGetExample { + public static void main(String[] args) { + Optional optional = Optional.empty(); + + // orElseGet 메서드를 사용하여 대체 값을 제공 + String result = optional.orElseGet(() -> generateDefaultValue()); + System.out.println("Result: " + result); + } + + // 대체 값을 생성하는 메서드 + public static String generateDefaultValue() { + System.out.println("Generating default value..."); + return "Default Value"; + } +} +``` +- orElseThrow() +> Optional 객체가 비어있다면, Exception(개발자가 구현한 프로그램 로직 상에 처리할 수 없는 입력이 주어지면 예외 가 발생)을 발생. +>Optional 객체가 비어 있을 때 예외를 던지기 위해 사용됩니다. +- toString +>Optional의 내부값을 String 문자열로 바꿔 반환. +- hashCode() +> Optional 객체의 HashCode(체를 식별하는 하나의 정수값)를 반환. \ No newline at end of file diff --git a/kimjeakwan/spring/20240520.md b/kimjeakwan/spring/20240520.md new file mode 100644 index 0000000..8f59578 --- /dev/null +++ b/kimjeakwan/spring/20240520.md @@ -0,0 +1,134 @@ + +# IOC(Inversion of Control) +- 영어 그대로 제어의 역전이다. +- 제어의 역전이란 메서드나 객체의 호출 작업을 개발자가 아닌 스프링에게 제어권을 넘기는 것을 말한다. +- 이전까지는 개발자가 객체의 생성을 관리하며 제어했지만, 스프링을 사용하게 되면 스프링 컨테이너에게 제어권을 넘겨 스프링 컨테이너가 흐름을 제어하게 된다. +- 개발자가 직접 객체를 생성하지 않고, 객체의 생명 주기 관리를 외부에 위임한다. +- 여기서 '외부'는 스프링에서 관리하는 Spring Container 또는 IoC Container라고 한다. +- 객체의 생성과 의존성 관리를 담당한다. +# DI +- 사용할 객체를 직접 생성하지 않고 외부 컨테이너가 생성한 객체를 주입받아 사용하는 방식을 말한다. +- 스프링에서는 의존성 주입으로 직접 객체를 생성하지 않고 제어권을 스프링 컨테이너로 넘긴다. +- 객체를 직접 생성하는 것이 아니라 외부에서 생성 후 주입시켜 주는 방식이라 할 수 있다. +- 의존성 주입(Dependency Injection)을 통해 객체 간의 결합도를 낮추는 역할을 합니다. +# 의존성 주입 방법 +- 생성자를 통한 의존성 주입 +- 필드 객체 선언을 통한 의존성 주입 +- setter를 통한 의존성 주입 +1. package com.example.demo; +```java +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; + +@Controller +public class MyController { + private final MyService myService; + + @Autowired + public MyController(MyService myService) { + this.myService = myService; + } + + public void doSomething() { + System.out.println(myService.serve()); + } +} +``` +2. 필드 객체 선언을 통한 의존성 주입 +```java +@RestController +public class DIController { + + @Autowired + private MyService myService; + + //Controller Codes +} +``` +3. setter를 통한 의존성 주입 +```java +@RestController +public class DIController { + + MyService myService; + + @Autowired + public void setMyService(MyService myService) { + this.myService = myService; + } + + //Controller Codes +} +``` +# Bean +- 스프링은 스프링 컨테이너(스프링에서 자바 객체들을 관리하는 공간을 말합니다..)를 통해 객체를 관리하는데, 스프링 컨테이너에 관리되는 객체를 Bean 이라고 한다. +- 재사용 가능한 소프트웨어 컴포넌트이다. +- 빈은 인스턴스화된 객체를 의미하며, 스프링 컨테이너에 등록된 객체를 스프링 빈이라고 한다. +# bean 생성방법 +- +```java + + +IHelloService helloService = new IHelloService() +``` +# Application Context +- Spring framework에서는 스프링 컨테이너를 통해 객체(Bean)들을 관리한다.여기서 스프링 컨테이너가 ApplicationContext이다. +- ApplicationContext는 BeanFactory를 구현하고 있어 BeanFactory(빈을 생성하고 의존관계를 설정하는 기능을 담당하는 가장 기본적인 IoC 컨테이너이자 클래스를 말한다.)의 확장된(국제화 기능,환경 변수 관련 처리, 애플리케이션 이벤트, 리소스 조회) 버전이라고 생각하면 좋다. +- 빈의 생성, 관계 설정 등의 제어를 총괄하는 것에 초점을 맞춘 것이다. +- Application Context에서 미리 생성된 빈을 가져와 사용하는 것이 가능합니다. +- 싱글톤 패턴이란 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴인데 스프링 컨테이너는 싱글턴 패턴을 적용하지 않아도, 객체 인스턴스를 싱글톤으로 관리한다. +- 빈(객체)를 스프링 컨테이너에 등록하고, 빈 조회 요청 시 새로 생성하지 않고 스프링 컨테이너에서 빈을 찾아서 반환한다. +- 애플리케이션 구성 요서 간의 의존성을 자동으로 주입한다. +# Application Context 처리 과정 +1. 클라이언트에서 해당 빈을 요청하기 전 Application Context는 @Configuration 이 붙은 클래스들을 설정 정보로 등록합니다. 해당 클래스 안에 존재하는 @bean 이 붙은 메소드의 이름으로 빈 목록 생성 +2. 클라이언트가 해당 빈을 요청합니다. +3. Application Context는 자신의 빈 목록에서 요청한 이름이 있는지 찾습니다. +4. Application Context는 설정 클래스(Configuration Class) 부터 빈 생성을 요청하고 생성된 빈을 돌려줍니다. +- beanfactory 의 방식은 getBean() 메서드에 의해 요청을 받는 시점에 인스턴스를 만들고 되고 로드된다. +- Application Context의 방식은 1번으로 모든 싱글톤 빈들이 인스턴스화 된다. 그러므로 빈이 여러 개라면 시간이 소요될 것이다 2번째에 는 미리 컨테이너에서 만들어진 빈들이 클라이언트로 리턴된다. +# @Configuration과 싱글톤 컨테이너 +- 스프링은 @Configuration이 붙은 클래스를 설정 정보로 사용한다 +- 스프링은 CGLIB이라는 바이트코드를 조작하는 라이브러리를 사용해서 AppConfig 클래스를 상속받은 다른 클래스(AppConfig@CGLIB)를 생성한다. +- 이 클래스(AppConfig@CGLIB)를 스프링 빈에 등록한다. 그리고 이 클래스는 빈들을 싱글톤이 되도록 보장해준다. +# @RequestBody 과 @ResponseBody +- 클라이언트 -> 서버 요청 : @RequestBody +- 서버 -> 클라이언트 응답 : @ResponseBody +- @RequestBody 어노테이션은 HTTP 요청의 body 내용을 자바 객체로 변환하는 역할을 한다. +- json 기반의 http body를 자바 객체로 변환 +- 클라이언트가 전송한 JSON(문법으로 구조화된 데이터를 표현하기 위한 문자 기반의 표준 포맷이다), XML 등의 데이터를 서버에서 자바 객체로 변환하여 사용할 수 있습니다. +- HTTP 요청 Body를 자바 객체로 Conversion해준다. 그냥 변환되는 것이 아니라 HttpMessageConverter에서 Request Header(요청 헤더)에 있는 Content-Type을 확인하고 JSON을 컨버팅 할 수 있는 컨버터(Jackson2ObjectMapperBuilder)를 선택해서 사용한다. +- HTTP 요청 본문에 포함된 JSON 데이터를 VO 객체로 매핑하는 매우 유용한 도구입니다. 이를 사용하면 클라이언트와 서버 간의 데이터 교환을 손쉽게 처리할 수 있습니다. +- HTTP BODY에 존재하는 JSON 데이터를 +자바의 VO로 받을수 있도록 매핑해주는 역할을 해줍니다. +```java +@Getter +public class UserInfo { + private String name; + private String nickName; +} +@GetMapping("/userInfo") +public void getUserInfo(@RequestBody UserInfo userInfo){ + log.info("userInfo : {}",userInfo); + log.info("userInfo, Name : {}", userInfo.getName()); + log.info("userInfo, NickName : {}", userInfo.getNickName()); +} +``` +- @ResponseBody 어노테이션은 자바 객체를 HTTP 요청의 body 내용으로 매핑하는 역할을 합니다. +- 자바 객체를 json 기반의 HTTP Body로 변환 +- VO를 JSON 형태로 변환해서 HTTP BODY에 담는 어노테이션 입니다. +- @RestController를 사용하는 경우 반환값에 자동으로 @ResponseBody 어노테이션이 붙게 된다. 따라서 자바 객체를 반환하면 알아서 Json 형식으로 매핑해서 응답한다. +- HTTP 메시지 바디에 직접 데이터를 입력합니다 +- @ResponsBody를 사용하면 뷰 리졸버를 사용하지 않고 HTTP의 BODY에 문자 내용을 직접 반환한다.  +![alt text](<스크린샷 2024-05-21 210434.png>) +- 사진 처럼 페이지 소스가 json 처럼 나온나.따라서 Controller가 매핑을 받아 동작할 때 @ResponsBody 어노테이션이 있으면 뷰 리졸버가 아닌 HttpMessageConverter가 처리를 하게 된다.  + +```java + @ResponseBody + @GetMapping("/userInfo") + public UserInfo getT(@RequestBody UserInfo userInfo) { + log.info("userInfo : {}", userInfo); + log.info("userInfo, Name : {}", userInfo.getName()); + log.info("userInfo, NickName : {}", userInfo.getNickName()); + return userInfo; + } +``` diff --git "a/kimjeakwan/spring/\354\212\244\355\201\254\353\246\260\354\203\267 2024-05-21 210434.png" "b/kimjeakwan/spring/\354\212\244\355\201\254\353\246\260\354\203\267 2024-05-21 210434.png" new file mode 100644 index 0000000..eb26b52 Binary files /dev/null and "b/kimjeakwan/spring/\354\212\244\355\201\254\353\246\260\354\203\267 2024-05-21 210434.png" differ