[ Object equals ]

equals 메서드는 같은 객체(인스턴스) 일 경우에만 동일하다고 판단.

reflexive : x.equals(x) 는 항상 참

symmetric : x.equals(y) 가 참이라면 y.equals(x) 역시 참이어야 한다

transitive : x.equals(y) 가 참이고 y.equals(z) 가 참일 때 x.equals(z) 역시 참이어야 한다

consistent : x.equals(y)가 참일 때 equals 메서드에 사용된 값이 변하지 않는 이상 몇번을 호출해도 같은 결과가 나와야 한다

x가 null이 아닐 때 x.equals(null) 은 항상 거짓이어야 한다

 

[ JPA 에서의 equals ]

엔티티 매니저의 영속성 컨텍스트에서 1차 캐시를 이용해 같은 ID의 엔티티를 항상 같은 객체로 가져올 수 있다. 하지만 1차 캐시를 초기화 한 후 다시 데이터베이스에서 동일한 엔티티를 읽어오는 경우 초기화 전에 얻었던 객체와 초기화 이후에 얻은 객체가 서로 다른 객체로 생성된다.

이는 equals 메서드의 consistent 원칙을 위반하는 것이며 엔티티는 자바 객체라기 보단 데이터베이스 테이블 레코드에 가깝기 때문에 엔티티 객체의 필드(pk)가 동일하다면 같은 레코드, 즉 객체라고 판단해야 한다. 

이와 같은 이유로 equals 메서드와 hashCode 메서드를 재정의 해야 한다.

 

* 준영속 상태의 엔티티 간 비교, 비교할 두 인자가 둘 다 null 인 상태에서의 비교 등을 고려하여 

Objects.hash 메서드를 사용하여 hashCode 구현

 

https://velog.io/@park2348190/JPA-Entity%EC%9D%98-equals%EC%99%80-hashCode

 

반응형

'back > JPA' 카테고리의 다른 글

[JPA] cascade  (0) 2022.11.10
[JPA] JPQL, QueryDSL  (0) 2020.03.21
[JPA] JPA 영속성 컨텍스트  (0) 2020.03.08
[JPA] 연관관계 매핑 : 단방향, 양방향 매핑  (0) 2020.03.01
[JPA] JPA 기초 설정 및 entity 필드 매핑  (0) 2020.02.27

[ 정적팩토리메소드 패턴 ]

https://7942yongdae.tistory.com/147

 

[ 정적팩토리메소드 패턴 네이밍 룰 ]

1. from: 하나의 매개변수를 받아서 해당 타입의 인스턴스 생성
2. of: 여러개의 매개변수를 받아서 인스턴스를 생성
3. instance or getInstance: 인스턴스를 반환하지만 동일한 인스턴스임을 보장하지 않는다.
4. create or newInstance: instance 혹은 getInstance와 같지만, 매번 새로운 인스턴스를 생성하여 반환함을 보장.
5. getType: getInstance와 같으나 생성할 클래스가 아닌 다른 클래스에 팩토리 메소드를 정의할 때 사용. (호출하는 클래스와 다른 타입의 인스턴스를 반환할때 사용)

FileStore fs = Files.getFileStore(path);

6. newType: getType과 같지만 매번 새로운 인스턴스를 반환

7. type : getType 과 newType의 간결한 버전

List<Test> list = Collections.list(test);

https://velog.io/@saint6839/%EC%A0%95%EC%A0%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9C-%EB%84%A4%EC%9D%B4%EB%B0%8D-%EB%B0%A9%EC%8B%9D

 

[ 생성자에 코드를 넣지 말자 ]

https://cozzin.tistory.com/71

 

※ 디미터법칙

https://tecoble.techcourse.co.kr/post/2020-06-02-law-of-demeter/

1. 객체 자신의 메서드들

2. 메서드의 파라미터로 넘어온 객체들의 메서드들

3. 메서드 내부에서 생성, 초기화된 객체의 메서드들

4. 인스턴스 변수로 가지고 있는 객체가 소유한 메서드들

 

 

반응형

[ 일급콜렉션 : First Class Collection ]

Collection 을 Wrapping 한 클래스

규칙 8: 일급 콜렉션 사용
이 규칙의 적용은 간단하다.
콜렉션을 포함한 클래스는 반드시 다른 멤버 변수가 없어야 한다.
각 콜렉션은 그 자체로 포장돼 있으므로 이제 콜렉션과 관련된 동작은 근거지가 마련된셈이다.
필터가 이 새 클래스의 일부가 됨을 알 수 있다.
필터는 또한 스스로 함수 객체가 될 수 있다.
또한 새 클래스는 두 그룹을 같이 묶는다든가 그룹의 각 원소에 규칙을 적용하는 등의 동작을 처리할 수 있다.
이는 인스턴스 변수에 대한 규칙의 확실한 확장이지만 그 자체를 위해서도 중요하다.
콜렉션은 실로 매우 유용한 원시 타입이다.
많은 동작이 있지만 후임 프로그래머나 유지보수 담당자에 의미적 의도나 단초는 거의 없다. - 소트웍스 앤솔로지 객체지향 생활체조편

[ 일급콜렉션의 예 ]

// 콜렉션 사용
final List<Integer> lottoTicket = new ArrayList<>();
lottoTicket.add(4);
lottoTicket.add(11);
lottoTicket.add(15);
lottoTicket.add(21);
lottoTicket.add(33);
lottoTicket.add(45);
// 일급콜렉션 (Wrapping)
public class LottoTicket {
	
    private final List<Integer> lottoNumbers;
    
    public LottoTicket(List<Integer> lottoNumbers){
    	this.lottoNumbers = lottoNumbers;
    }
}

 

[ 일급콜렉션을 왜 써야 하는가? ]

1. 비지니스에 종속적인 자료구조 : Wrapper 클래스(일급콜렉션 클래스) 내에서 콜렉션에 대한 유효성 검사 및 정제 등의 로직을 포함하여 비지니스에 필요한 자료구조를 만들 수 있다. (ex: LottoTicket 내에서 Lotto 번호 범위(1~45)에 대한 유효성 검사 로직을 추가)

2. 불변 : 콜렉션 변수를 final 로 선언시 재할당만 불가할 뿐, 콜렉션에 .set 등이 가능하여 불변성 보장이 되지 않는 반면 일급콜렉션 사용시 선언 후엔 조작이 불가.

3. 상태와 행위를 한 곳에서 관리 : 값과 로직이 함께 존재 (ex: 일급콜렉션 클래스 내에 콜렉션의 합계를 구하는 메소드를 구현하여 상태와 행위를 한 곳에서 관리)

4. 이름이 있는 컬렉션 : Wrapping 한 클래스를 사용하므로 인스턴스 생성시 new ArrayList<>() 대신 new LottoTicket(createNonDuplicatedNumbers()) 이 가능.

 

 

* 일급콜렉션에서 Wrapping 한 인스턴스 변수를 외부에서 필요로 할 땐?

Collections.unmidifiableList 를 사용하여 리턴하여 외부에서의 변경을 막는다.

 

출처 및 참고 : 

https://jojoldu.tistory.com/412

 

https://velog.io/@injoon2019/%EC%9D%BC%EA%B8%89%EC%BB%AC%EB%A0%89%EC%85%98%EC%9D%98-%EB%B6%88%EB%B3%80%EA%B0%9D%EC%B2%B4-unmodifiable-%EB%B0%A9%EC%96%B4%EC%A0%81-%EB%B3%B5%EC%82%AC

반응형

'back' 카테고리의 다른 글

[TDD] 테스트주도개발  (0) 2022.10.04
JWT  (0) 2020.11.18
[gradle] jar build, war build  (0) 2020.03.25

[ TDD란 ]

Test Driven Development 의 약자로 테스트 코드를 작성하고 프로덕션 코드를 개발하는, 테스트에서 부터 개발이 이뤄지는 테스트가 주도하는 개발 방법.  

TDD = TFD(Test First Development) + 리팩토링

 

[ TDD 원칙 ]

실패하는 단위 테스트를 작성할 때 까지 프로덕션 코드를 작성하지 않는다.

컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성.

현재 실패하는 테스트를 통과할 정도로만 실제 코드 작성.

 

[ TDD 는 어떻게 해야하나 ]

요구사항 분석을 통한 대략적인 설계를 한 후 객체를 추출

UI, DB 등과 의존관계를 가지지 않는 핵심 도메인 영역을 집중 설계

Controller , View 보단 우선적으로 Domain(Model) 영역을 1차적으로 단위테스트 작성

 

 

 

반응형

'back' 카테고리의 다른 글

[Java] 일급콜렉션 : First Class Collection  (0) 2022.10.06
JWT  (0) 2020.11.18
[gradle] jar build, war build  (0) 2020.03.25

[ GC : Garbage collector ]

JVM 메모리는 크게 class / stack / heap 영역으로 나누어지며,

GC 는 heap 영역을 대상으로 수행된다.

 

Heap 영역은 

Young / Old / Perm 영역으로 나눌 수 있으며 (java 8부터 Perm 영역은 제거되었음)

Young 영역은 

Eden , survivor 0, survivor 1 로 나눌 수 있다.

 

최초 객체 생성시 Eden 영역에 할당되며,

Eden 영역이 다 찼을 경우 reachable (접근 가능한 상태) 한 객체는 survivor 0로 옮기고 Eden 영역을 정리한다 (minor GC)

반복적으로 Eden 영역을 정리하다 survivor 0 이 다 찬 경우, reachable 한 객체를 survivor 1 로 옮긴 후 survivor 0 을 비워준다.

객체의 age 가 특정 임계점 도달시 Old 영역으로 객체를 옮겨준다 (promote)

위 과정을 반복하다 Old 영역도 다 차게되면 Full GC (major GC) 가 발생한다.

 

GC 수행시 아래 작업을 공통적으로 수행

Mark and Sweep : Mark(사용되는 메모리와 사용되지 않는 메모리 구분), Sweep(사용되지 않는 메모리 해제)

Stop the world : GC 수행하는 쓰레드를 제외한 모든 쓰레드 작업 중단

 

[ GC 알고리즘 종류 ]

1. Serial GC : 싱글쓰레드로 GC 수행

2. Parallel GC : Young 영역 GC 를 멀티쓰레드로 수행 (java 8)

3. Parallel Old GC : Young , Old 영역 모두 GC를 멀티쓰레드로 수행 (java 8)

3. CMS GC : 

4. G1 GC : Heap 을 일정한 크기의 region 으로 나눔. (java 9)

 

 

 

https://mangkyu.tistory.com/118

https://velog.io/@injoon2019/CS-%EC%A0%95%EB%A6%AC-GC-Garbage-Collector

 

 

 

 

 

반응형

 

https://jwt.io/

 

[JWT]

Json Web Token 의 약자로 토큰값 자체에 데이터를 가지고 있는 인증 토큰.

.으로 구분되는 3개 영역, Header.Payload.Signature 으로 나뉘어 진다. 

모든 영역은 Base64로 인코딩 되어 있다.

* Base64란? Binary Data를 Text로 바꾸는 Encoding 방법 중 하나로 Binary Data를 Character set 에 영향을 받지 않는 공통 ASCII 영역의 문자로만 이루어진 문자열로 바꾸는 Encoding.

 

[Header.Payload.Signature]

1. Header : 토큰에 사용된 알고리즘(SHA256, HS512 등)과 MIME 타입(보통 "typ" : "JWT" 사용)

2. Payload : 토큰의 바디로써 Claim(User Id 와 같은 Entity 정보) 정보를 담고 있음.

  암호화 되어있지 않고 단순 Base64 인코딩이 되어있으므로 패스워드와 같이 중요한 데이터를 담지 않도록 주의

3. Signature : Header 와 Payload 가 위변조 되었는지 검증하기 위한 부분으로써 Header와 Payload 를 base64 encoding 해서 만든 두 값을 . 로 이어 붙이고 Header 에서 지정한 알고리즘(alg)로 인코딩하여 Signature 를 만듬.

 

https://blog.outsider.ne.kr/1160

반응형

'back > SECURITY' 카테고리의 다른 글

[SECURITY] Authentication vs Authorization  (0) 2022.08.16

 

Authentication (인증) 과 Authorization (인가) 의 차이

 

인증 : 유저가 누구인지 확인

인가 : 유저에게 권한을 부여

 

반응형

'back > SECURITY' 카테고리의 다른 글

[SECURITY] JWT  (0) 2022.08.16

 

[compileOnly vs rumtimeOnly]

compileOnly : compile시 필요한 library. compileClasspath 에만 들어감 (대표적으로 lombok)

runtimeOnly : rumtime시 필요한 library. runtimeClasspath 에만 들어감 (대표적으로 h2database)

 

[compile(api) vs implementation]

implementation : 지정한 라이브러리만 빌드

compile : 의존하고 있는 상위 라이브러리 까지 빌드

* compile 키워드는 gradle 7.x 부터 deprecated 되었음 (api 로 대체)

 

A > B > C 의존성을 갖는 상황, C 가 변경되었을 때

compile : A, B 까지 rebuild

implementation : B 만 rebuild 

* compile(api) 은 프로젝트가 무거워지므로 사용을 지양할 것

https://kotlinworld.com/317

https://medium.com/mindorks/implementation-vs-api-in-gradle-3-0-494c817a6fa

https://stackoverflow.com/questions/44413952/gradle-implementation-vs-api-configuration

 

annotationprocessor : 

 

https://tomgregory.com/annotation-processors-in-gradle-with-the-annotationprocessor-dependency-configuration/#:~:text=Annotation%20processing%20is%20a%20Java,such%20as%20classes%20or%20documentation.

 

 

 

https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph

 

 

 

반응형

 

SIFT Appender 를 사용하여 로그 분기처리

 

[설정]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?xml version="1.0" encoding="UTF-8"?>
 
<configuration>
 
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}[%-5level] : %msg%n</Pattern>
        </encoder>
    </appender>
 
    <appender name="TST" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}[%-5level]-%msg%n</Pattern>
        </encoder>
    </appender>
 
    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
        <discriminator>
            <key>discr</key>
            <defaultValue>type</defaultValue>
        </discriminator>
        <sift>
            <appender name="FILE-${discr}" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>/${discr}.log</file>
                <layout class="ch.qos.logback.classic.PatternLayout">
                    <Pattern>%d [%thread] %level %mdc %logger{35} SIFT- %msg%n</Pattern>
                </layout>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <fileNamePattern>/${discr}_%d{yyyy-MM-dd-HH-mm}.%i.log</fileNamePattern>
                </rollingPolicy>
            </appender>
        </sift>
    </appender>
 
 
    <logger name="jpabook.jpashop.service.OrderService" level="error" additivity="false">
        <!--<appender-ref ref="TST"/>-->
        <appender-ref ref="SIFT"/>
    </logger>
 
    <root level="debug">
        <appender-ref ref="CONSOLE"/>
    </root>
 
 
</configuration>
cs

 

[테스트]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.slf4j.MDC;
 
@Slf4j
public class Sample {
    public void testLog(){
        MDC.put("discr""TYP1");
        //log.
        log.trace("test trace");
        log.debug("test debug");
        log.info("test info");
        log.warn("test warn");
        log.error("test error");
 
        MDC.put("discr""TYP2");
        log.error("test error222");
    }
}
cs

 

[결과]

 

* ThreadPool 사용시 MDC key값을 전달받지 못함.

 : MDC.setContextMap 으로 key 값 전달가능

 참고 : https://stackoverflow.com/questions/6073019/how-to-use-mdc-with-thread-pools

 

* slf4j MDC 를 사용하지 않더라도, strategy pattern 과 같은 디자인 패턴을 사용하고, 분기처리할 구현체에 logger 를 지정하여 패키지 경로마다 별도 로그 파일 및 별도 경로의 로그파일에 로그 적재가 가능할 듯.

 

반응형

[Window / Mac]

Ctrl + X : 한줄지우기(ctrl+D)

Ctrl + Alt + V : 변수선언

Ctrl+Shift+C : 커서 파일에 두고 수행시 파일경로 복사

Shift+F10 : 실행

Ctrl+Shift+F9 : recompile

Ctrl+Shift+T : test 생성 (mac : command shift T)

Ctrl+Shift+방향키 : 블럭이동 (eclipse : Ctrl+방향키)

Alt + enter : 아직 생성하지 않은 (선언한) 객체에 커서두고 실행시 create class 

Ctrl + Alt + 방향키 : 이전파일로 돌아가기 (alt+방향키)

Alt + Shift + L : beautify (줄정렬) ctrl + shift + f

Ctrl + Shift + F : 호출부 찾기 ctrl + shift + g

Alt + enter : import (mac : option + enter)

Ctrl + Alt + N : 여러줄 로직을 하나로 줄이기 (ex: 객체 선언부와 리턴이 각개로 있을 경우 리턴 바로하도록)

Ctrl + Alt + M : 선택된 로직 덩어리를 메소드로 만들어버리기

Ctrl + Alt + P : 변수에 커서를 두고 단축키 입력시 변수를 파라미터로 빼줌

Ctrl + Alt + V : 메소드에 커서 두고 단축키 입력시 메소드 리턴값을 받는 변수 좌측에 선언됨

Ctrl + H : eclipse Ctrl+T

Alt + Insert : generate Constructor (mac : cmd+N)

Ctrl + o : override method (오버라이드 가능한 메소드 목록 불러오기 및 오버라이딩)

Ctrl + e : 최근 열었던 파일 리스트 조회

Ctrl + Ctrl + 방향키 : 멀티라인 셀렉트

 

[Mac]

cmd + B = 호출부 찾기

ctrl + shift + 방향키 = 블럭이동

cmd + 1 = project view

shift + shift (연타) = search 창

cmd + option + V = 리팩토링 (변수 빼기)

cmd + shift + F = 퀵서치

cmd + option + 방향키 = 이전 이후 파일로 이동

ctrl + shift + O = 파일찾기 (ctrl + shift + R (이클립스))

cmd + option + l = formatting

cmd + n = equals / hashcode overriding

 

[설정]

Eclipse 'Link with Editor' 기능: 좌측 프로젝트 트리에서 우상단의 툴팁 클릭 후 'Always Select Opened File' 클릭

 

[플러그인] IntelliJ 유용한 Plugin

.ignore

Atom Material Icons

CodeGlance Pro

GitToolBox

Grep Console

Key Promoter X

Korean Language Pack (미사용.. 영어에 익숙해지자)

Meterial Theme UI

Rainbow Brackets

 

 

 

 

반응형

'etc.' 카테고리의 다른 글

[etc.] nativeQuery 복붙할 때 따옴표(") 제거하기  (0) 2023.04.19
Slack reminder 푸시 설정  (0) 2023.04.07
티스토리 소스코드 넣기  (0) 2019.02.12

+ Recent posts