Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kimjaekwan's java and spring #33

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions kimjeakwan/java/20240520.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# 자바의 optional
- 정의되지 않은 객체에 대해 NULL값을 고려하게 되는 경우가 발상핸다. 이떄 안정적인 실해을을 위해서는 NULL값을 처리해 NPE가 발생하지 않게 체크해야 한다.
- optional는 NULL이 올 수 있는 값을 감싸는 Wrapper 클래스로, NPE가 발생하지 않도록 도와준다.
- optional 클래스는 value에 값을 저장하기 떄문에 NULL이더라고 바로 NPE가 발생하지 않는다.
# optional 클래스 주요 메서드
- empty()
> 기능: 비어있는 Optional 객체를 생성.
> 리턴값: Optional<T>
- of(T value)
> 기능: 전달된 값으로 새로운 Optional 객체를 생성.
>리턴값: Optional<T>
- ofNullable()
> 기능: 비어있을 수 있고, 아닐 수도 있는 Optional 객체를 생성.
>반환값: Optional<T>
- equals(object obj)
> 기능: Optional 객체의 값을 비교.
> 리턴값: boolean
- filter(Predicate<? Super T> predicate)
>기능:Optional 객체의 값을 조건에 따라 필터링.
>리턴값:Optional
- map(Function<? Super T, ? Extends U> mapper)
>기능:Optional 객체 내부의 값을 변환하여 결과를 새로운 Optional 객체로 반환.
> 일반적인 변환을 수행하여 Optional<T>를 Optional<U>로 변환합니다.
>리턴값: Optional<U>
- flatMap(Function<? Super T, ? Extends Optional<? Extends U>> mapper)
> 기능:중첩된 Optional
> Optional 객체의 값을 변환하고, 변환된 값이 Optional 객체인 경우에 사용됩니다.
>flatMap 메서드를 사용하면 중첩된 Optional 객체를 하나의 optional 객체로 변환하여 하나의 Optional 객체로 다룰 수 있다.
> 리턴값: Optional<U>
- flatmap 과 map 의 차이점
> map 매서들 사용하여 중첩된 구조를 만들수 있다.
> flatmap 매서드를 사용하여 중첩된 구조를 하나의 구조로 만든다.
- get()
> Optional 객체의 값을 가져온다.
(만약 값이 존재하지 않는 경우, NoSuchElementException이 발생)
- isEmpty
> Optional 객체가 비어있는지 확인 한다.
>Optional 객체에 값이 없는 경우 true를 반환하고, 값이 있는 경우 false를 반환한다.
- ispresent()
> optiomal 객체가 있는지 확인한다.
- ifpreseint(Consumer<? Super T> action)
> Optional 객체가 있다면 내부 연산을 실행한다.
- ifPresentOrElse()
> Optional 객체가 있다면 내부 연산을 실행, 없다면 또 다른 내부 연산을 실행
```java
import java.util.Optional;

public class IfPresentOrElseExample {
public static void main(String[] args) {
// 값이 있는 Optional 객체 생성
Optional<String> nonEmptyOptional = Optional.of("Hello, world!");

// 값이 없는 Optional 객체 생성
Optional<String> 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<String> optional = Optional.empty();
Optional<String> 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<String> 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(체를 식별하는 하나의 정수값)를 반환.
134 changes: 134 additions & 0 deletions kimjeakwan/spring/20240520.md
Original file line number Diff line number Diff line change
@@ -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
<bean id="helloService" class="com.example.myapp.di.HelloService"/>

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;
}
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.