1) pom.xml 추가 org.modelmapper modelmapper 2.3.8 2) ModelMapper 사용 UserEntity.java @Setter @Getter @Entity @Table(name = "users") public class UserEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long idx; @Column(nullable = false, length = 50) private String userId; @Column(nullable = false, length = 50) private String userName; } UserDto.java @Data public class UserDto {..
설정 1) build.gradle 의존성 추가 implementation 'org.springframework.boot:spring-boot-starter-validation' 2) @Valid 어노테이션 추가 /** * 회원 등록 * @param memberDto * @return */ @PostMapping("") public ResponseEntity addMember(@ModelAttribute @Valid MemberDto memberDto) { /* 패스워드 암호화 */ memberDto.setMemberPwd(passwordEncoding.encode(memberDto.getMemberPwd())); Member member = memberService.addMember(memberDto);..
구현 1) build.gradle 의존성 추가 implementation 'org.springframework.boot:spring-boot-starter-security:2.4.2' 2) CommonEncoder.java 생성 @Component public class CommonEncoder implements PasswordEncoder { private final PasswordEncoder passwordEncoder; public CommonEncoder() { this.passwordEncoder = new BCryptPasswordEncoder(); } public CommonEncoder(PasswordEncoder passwordEncoder) { this.passwordEncoder ..
상황 SpringBoot 프로젝트를 진행하면서 로그인/로그아웃 API를 개발할 단계가 되었다. SpringBoot 프레임워크 프로젝트에 세션 관리를 Redis로 진행해보자. Redis 설치 우선 프로젝트가 Redis를 연동할 수 있도록 Redis를 설치해야한다. docker에 redis를 간단하게 설치하였다. docker redis 설치 포스팅 : devfunny.tistory.com/424?category=820624 docker로 redis 설치 (with docker-compose) Redis 이미지 설치 docker pull redis docker-compose 파일 생성 version: '3.0' services: redis1: image: redis command: redis-server --..
application.yml 파일 spring: datasource: url: jdbc:oracle:thin:@127.0.0.1:1521:XE username: seohae password: pawd123 driver-class-name: oracle.jdbc.driver.OracleDriver Ojdbc6 나의 프로젝트 버전은 아래와 같다. id 'org.springframework.boot' version '2.4.2' Oracle DB 연동을 하기위해 Ojdbc6 을 build.gradle 에 추가했다. runtimeOnly 'com.oracle.database.jdbc:ojdbc6' 하지만 제대로 연동되지 않는다. Ojdbc6 을 포함하게되면 application.yml 파일 안의 driver-c..
ResponseEntity 요즘 RESTFul API 가 많이 사용되고있는데, Restful API에서 return Type으로 사용되고있는 ResponseEntity 에 대하여 알아보자. 설명 예시 HTTP 상태코드 제어 ResponseEntity.status(HttpStatus.OK).body(testVO) 결과 데이터를 body에 담아 return ResponseEntity.status(HttpStatus.OK).body(testVO) ResponseEntity는 @ResponseBody 어노테이션과 같은 의미로, ResponseEntity를 return Type으로 지정하면 JSON (default) 또는 Xml Format으로 결과를 내려준다. 200 OK 1) return ResponseEnt..
Reactive 의 예시 Reactive의 뜻은 반응형이다. 리액티브를 이해하기 위해서, 하나의 상황을 예로 들어보자. 한 어플리케이션에서 시간당 평균 약 1,000명의 사용자가 방문한다고 가정해보자. 톰캣을 웹 서버로 실행하고, 500개의 스레드로 톰캣 스레드 풀을 구성했다. 위 상황에서, 사용자 요청에 대한 평균 응답 시간은 약 0.250ms이다. 그럼 1초에 2,000명의 사용자의 요청을 처리할 수 있다. 그렇다면 평균 약 1,000명의 사용자가 들어오는 위 어플리케이션의 웹 서버는 평균 부하를 처리하기에 매우 충분하다. 요악하면 이 경우는 처리 능력을 기준으로 애플리케이션을 구성한 것이다. 그런데 만약, 특정 할인날에 폭발적인 고객 증가로 서버 부하가 발생했다고 가정해보자. 스레드 풀에 사용자 요..
스프링 DI (Dependency Injection)란? 자바에서 객체를 생성하기 위해서는 Test test = new Test(); 을 사용한다. new 연산자를 사용하여 인스턴스를 생성하는 행위이다. 이와 다르게, DI는 위 코드처럼 객체를 생성시키는게 아닌, 외부에서 객체를 생성해서 주입시켜주는 방식이다. DI는 필요한 객체를 해당 .java 파일 안에서 new 연산자를 통해 생성하는 것이 아닌, 외부에서 생성된 객체 중 필요한 객체를 연결하는 것이다. 필드 주입 결론적으로, 필드 주입을 사용하는 것은 추천하지 않는다. @Autowired private Mapper mapper; 위 코드를 IntelliJ IDE에서 사용하면 @Autowired 에 경고가 뜨게된다. Field injection is..
스프링의 빈 오브젝트 스프링의 애플리케이션 컨텍스트는 IoC 컨테이너로써, 싱글톤을 저장하고 관리하는 싱글톤 레지스트리이다. 스프링은 여러 번에 걸쳐 빈을 요청하더라도 매번 동일한 오브젝트를 돌려준다. getBean() 메소드를 실행할 때마다 같은 오브젝트를 돌려준다. 스프링은 기본적으로 별다른 설정을 하지않으면, 내부에서 생성하는 빈 오브젝트를 모두 싱글톤으로 만든다. 왜 스프링은 싱글톤으로 빈을 만들까? 스프링이 주로 적용되는 대상은 자바 엔터프라이즈 서버환경이다. 자바 엔터프라이즈 서버환경이란, 서버 하나당 최대로 초당 수십에서 수백번씩 브라우저나 다른 시스템으로부터의 요청을 받아 처리할 수 있는 높은 성능이 요구되는 환경이다. 만약 매번 클라이언트에서 요청이 올때마다 각 로직을 담당하는 오브젝트를..
관심사의 분리 (Separation Of Concerns) 관심이 같은 것끼리는 하나의 객체 안으로 또는 친한 객체로 모이게 하고, 관심이 다른 것은 가능한 한 따로 떨어져서 서로 영향을 주지 않도록 분리하는 것이다. 어떠한 기준 없이 모으는 편이 처음엔 간단하고 쉽겠지만 언젠가는 여러 종류의 관심사(기준)를 적절하게 구분하고 따로 분리하는 작업을 해줘야한다. 관심사가 같은 것끼리 모으고 다른 것은 분리해줌으로써 같은 관심에 효과적으로 집중할 수 있게 만들어주는 것이다. 중복 코드의 메소드 추출 여러 메소드에 중복 코드가 구현되어있다고 가정해보자. 만약 메소드가 1~2개라면 어떠한 변경이 일어났을때 어려움이 없다. 하지만 만약 중복 코드를 가진 메소드가 몇 백개, 몇 천개라고 생각해보자. 중복 코드의 코..
개방 폐쇄 원칙 (OCP : Open-Closed Principle) 깔끔한 설계를 위해 적용 가능한 객체지향 설계 원칙 중의 하나로, ‘클래스나 모듈은 확장에는 열려있어야하고 변경에는 닫혀있어야한다.’라고 할 수 있다. 이 말은 즉 확장성은 높고 미래의 변화에 대한 준비를 철저히 하고있다는 얘기와 같다. 인터페이스에 의해 제공되는 확장 포인트는 확장을 위해 개방되어있고, 인터페이스를 이용하는 클래스는 자신의 변화가 불필요하게 일어나지 않도록 폐쇄되어있다. 인터페이스를 사용하여 확장 기능을 정의한 대부분의 API가 개방 폐쇄 원칙을 따르고있다. 인터페이스의 사용 위 개방 폐쇄 원칙에서 인터페이스의 확장성을 얘기했는데, 이를 더 깊이 이해하기 위해서 인터페이스에 대해 좀더 알아보자. 우선 추상화란, 어떤 ..
일반적은 프로그램의 흐름 1) mian() 메소드와 같이 프로그램이 시작되는 지점에서 다음에 사용할 오브젝트를 결정한다. 2) 결정한 오브젝트를 생성한다. 3) 만들어진 오브젝트에 있는 메소드를 호출한다. 4) 그 오브젝트 메소드 안에서 다음에 사용할 것을 결정하고 호출한다. 이 4가지 단계가 반복적으로 일어난다. 이런 프로그램 구조에서 각 오브젝트는 프로그램 흐름을 결정하거나 사용할 오브젝트를 구성하는 작업에 능동적으로 참여한다. 모든 오브젝트가 능동적으로 자신이 사용할 클래스를 결정하고, 언제 어떻게 그 오브젝트를 만들지를 스스로 결정한다. 모든 종류의 작업을 사용하는 쪽에서 제어하는 구조이다. 제어의 역전 제어의 역전이란, 위에서 설명한 일반적인 프로그램의 제어 흐름 구조가 뒤바뀌는 것이라고 설명할..