일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- JPA
- 링킹
- 토비의스프링
- AutoConfiguration
- Kotlin for Java Developers
- springwebmvc
- IOC
- Immutable
- String
- beanfactory
- 클린코드
- DesignPattern
- springboot
- lambda
- hibernate
- 프록시
- 토비의스프링3.1
- FunctionalInterfaces
- 링커
- 컴퓨터시스템
- Spring
- 빌드툴
- 자바
- exception
- ApplicationContext
- 메이븐
- gradle
- ORM
- DispatcherServlet
- java
- Today
- Total
목록프로그래밍 (78)
엔지니어로 가는 길
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/cjun7y/btqNiXbSWAu/zwNfNv5tdhyfr2eWIOo9e0/img.png)
결론 axios post의 두 번째 인자를 null로 주고, 세 번째 인자에 매개변수를 주어야 한다. (아니면 jquery를 사용해도 된다. 참고: github.com/axios/axios/issues/1281) 문제상황과 해결 방법 백엔드(Spring boot) /users/register로 오는 POST 요청을 담당하는 핸들러이다. (컨트롤러에 @RequestMapping("/users")가 붙어있는 상황이다.) User는 userId와 password라는 필드를 갖고 있어서 요청하는 쪽에서 매개변수로 userId, password를 넘겨주면 User라는 객체로 바인딩되어 핸들러에게 전달된다. 핸들러는 이 객체를 데이터베이스에 저장한다. 프론트(React) 결과 User에 아무것도 바인딩되지 않았다...
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/cBNw54/btqLFTpclqB/GlBiJpf5s3GRMFWK9SWw5K/img.png)
지난 글에서 프록시란 무엇인지 알아보았고, 간단한 프록시 예제를 하나 살펴보았다. 프록시(Proxy)란 무엇인지 자바 코드로 보자 프록시(Proxy)란 무엇인지 자바 코드로 보자 Proxy Proxy의 사전적 정의는 대리인이다. 자바에서 프록시는 타겟의 기능을 확장하거나 타깃에 대한 접근을 제어하기 위한 목적으로 사용하는 클래스를 말한다. 여기서는 기능을 확장하는 프록시 live-everyday.tistory.com 이번에는 지난 시간의 예제를 발전시켜 자바를 통해 다이나믹하게 프록시를 구현하는 방법을 살펴보도록 한다. '다이나믹하게'라는 뜻은 코드로 일일이 프록시를 만드는 것이 아니라 런타임에 프록시가 생성되는 것을 의미한다. 먼저 왜 다이나믹하게 프록시를 구현해야 하는지 살펴보자. 프록시 구현의 문제..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/kAbNa/btqLENUFNNu/B72HKljRlHj9qi2KOXjGS1/img.png)
프록시 Proxy의 사전적 정의는 대리인이다. 자바에서 프록시는 타겟의 기능을 확장하거나 타깃에 대한 접근을 제어하기 위한 목적으로 사용하는 클래스를 말한다. 여기서는 기능을 확장하는 프록시의 예시를 보도록 한다. Hello라는 클래스의 메소드가 대문자로 변환된 문자열을 리턴하게 하고 싶다고 해보자. 이때 프록시를 이용하면 Hello의 메소드를 변경하지 않은 채로 ‘대문자로 변환’이라는 부가 기능을 추가할 수 있다. 여러 구현 방법이 있지만 지금은 프록시의 개념을 이해하는 것이 목적이므로 인터페이스를 통해 간단하게 구현하는 방법을 알아보자. 위와 같이 Hello라는 이름의 인터페이스를 만든다. HelloTarget이라는 클래스를 만들어 Hello를 구현한다. 다음으로 HelloUppercase라는 또 다..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bf4m2G/btqKOCA12V6/ZPD4x0yPK7MKjKs6kmUEjk/img.png)
Immutable String은 immutable하다. Immutable이란 변하지 않는다는 뜻이다. 예시를 들어보자. 위와 같이 "Hello"를 담고 있는 str이라는 변수에 "Hello world"를 대입해주면 어떤 일이 벌어질까? "Hello"가 있던 공간에 " world"를 추가하는 것이 아니라 "Hello world"라는 새로운 문자열을 갖게 된다. 정확히는 str이 "Hello"가 있는 메모리 공간을 가리키던 상황에서 "Hello world"가 있는 메모리 공간을 가리키게 된다. (만약 위의 상황에서 String str2 = "Hello world"; 라는 코드를 추가한다면 이때 str2와 str1은 같은 곳을 가리키게 된다. 참고: Java String literal과 new String()..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/boNQfB/btqKBPUhiCo/Fy8e9XLNXsr2A7Ejruy750/img.png)
String literal vs new String() str1을 String literal이라 말한다. str1과 str2는 어떤 차이가 있을까. 위의 그림대로 문자열을 만들어보자 이때 s3와 s4는 같은 곳을 가리키고 있다. String literal은 같은 문자열인 경우 메모리 전체에서 하나만 존재함을 알 수 있다. 하지만 s1과 s2를 보면 같은 문자열임에도 s3, s4가 가리키는 곳과 다른 곳을 가리키고 있고, 심지어 s1과 s2끼리도 서로 다른 곳을 가리키고 있다. 즉, new 연산자를 통해서 String 객체를 만들면 문자열이 같아도 매번 다른 공간에 문자열이 생기는 것임을 알 수 있다. 테스트해보자. 동일성과 동등성 동일할 때와 동등할 때 모두 '같다'라는 단어를 사용할 수 있지만 그 뜻이..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bXeHtA/btqKjbJzoIU/RWg13WRnONqPPYL4Ulcls0/img.png)
Facade Pattern(퍼사드 패턴) 퍼사드 패턴은 서브시스템에 있는 인터페이스들에 대한 통합된 인터페이스를 제공한다. 퍼사드란 서브시스템을 더 쉽게 사용할 수 있도록 만드는 더 높은 수준의 인터페이스를 말한다. 퍼사드 패턴의 등장인물 및 역할은 다음과 같다. Facade: 클라이언트의 요청을 적절한 서브시스템 클래스에 위임한다. Subsystem classes: 서브시스템 기능을 구현한다. 서브시스템 클래스는 facade에 의해서만 사용된다. Client: Facade에게 특정 행동을 수행해달라고 요청한다. 온라인 쇼핑몰에서의 주문 시스템을 예로 들어보자. 현재의 상황에서 클라이언트는 서브시스템 클래스에 의해 구현된 서비스들과 다수의 상호작용을 해야하며, 서브시스템 클래스에 대한 정보를 알고 있어야..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/S1qYD/btqJVOQyXOe/4szP8T2L7ifvxBTU0eK7Ck/img.png)
@Embedded와 @Embeddable 다음과 같은 상황을 생각해보자. ToDo class 오늘 할 일 하나를 나타낸다. TDL class to-do-list를 나타낸다. List 타입의 객체를 프로퍼티로 갖는다. 이때 db에 위와 같은 정보를 저장하고 싶다면 어떻게 해야 할까? 가장 먼저 떠올린 방법은 ToDo를 하나의 테이블에 매핑하고, TDL 또한 하나의 테이블에 매핑한 뒤 두 클래스를 One-To-Many와 Many-To-One 관계를 맺게 하는 것이었다. 하지만 생각해보니 ToDo 클래스는 항상 TDL 안에서만 존재하며, TDL을 부르지 않고 ToDo만 불러올 일이 없을 것 같았다. 그래서 ToDo를 TDL의 Embedded로 설정하였다. Embedded로 설정하는 방법은 다음과 같다. ToD..
Modules 모듈은 하나 이상의 패키지를 갖는다. 모듈은 full Java app일 수도, a Java Platform API일 수도 또는 a third party API일 수도 있다. Modules Benefits 1. 군더더기를 제거함으로써 애플리케이션이 알맞은 덩치를 갖게 한다. 프로젝트 Jigsaw(JPMS = Java Platform Module System = Java Jigsaw = Project Jigsaw)의 일환으로 모든 Java Platform API는 별도의 모듈들로 쪼개졌다. 이로써 자신의 어플리케이션에서 필요한(실제로 사용할) 모듈들만 명시할 수 있게(가질 수 있게) 되었다. JPMS가 없는 Java 9 이전에는 모든 Java Platform API들을 애플리케이션에 패키징해야..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/Oak27/btqJnFllM9v/2Qs0bDmZo1tPpkAU7NkOSk/img.png)
Type Inference 자바 컴파일러가 타입을 추론하는 것을 Type Inference라고 한다. 컴파일러는 추론을 위해 method invocation과 그에 상응하는 declaration을 살펴본다. 추론 알고리즘은 인자의 타입을 결정하고, 가능한 경우에 결과가 할당되는 타입 또는 리턴되는 타입까지 결정한다. 추론 알고리즘은 모든 인자와 어울리는 선(공통 부모)에서 가장 구체적인 타입을 찾는다. 아래의 pick 메소드를 살펴보자. pick 메소드의 type 매개변수는 T이고 메소드의 매개변수 a1과 a2 모두 T이다. 하지만 pick을 호출할 때 첫 번째 인자로 String을 주었고 두 번째 인자로 ArrayList를 주었다. 이런 경우에 모든 인자와 어울리는 선(공통 부모)이란 Serializa..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/q1Zic/btqI6NQ3pSg/7kak2a7bBH2yi6br9XKf40/img.png)
위와 같은 클래스가 있을 때, 이런 Handler를 작성하고, 이런 테스트 코드를 작성한다면 어떻게 될까? 익숙한 예외가 발생한다. path variable로 들어온 "test"라는 문자열을 ToDo 클래스로 변환할 수 없다는 것이다. 이 경우 Formatter를 등록해야 하는데 오늘 우연히 다른 방법을 알게되었다. 위와 같이 String 타입 매개변수를 하나 갖는 생성자가 있는 경우 Formatter 없이도 conversion이 이루어진다. 굳이 String 타입 매개변수를 갖는 생성자를 추가하기 보다는 Formatter를 등록하는 편이 명시적이고 좋을 것 같다. 필요에 의해 그런 생성자를 만들어둔 경우라 하더라도 Formatter를 등록하는 게 좋을 것 같다. p.s. spring boot