오류 코드 (무한 루프)public MemberService(){ private final MemberService instance = new MemberService();} 무한 루프의 동작 원리final 키워드를 사용하면 해당 필드는 생성 시점에 반드시 초기화되어야 합니다.클래스 내부에서 다른 인스턴스를 생성하는 final 변수가 있다면, 이 필드를 초기화하기 위해 생성자가 호출될 때 새로운 인스턴스를 생성하게 됩니다.그런데 new MemberService()로 인스턴스를 생성할 때, 클래스 내에서 또 다른 new MemberService()가 호출되면 무한 재귀가 발생하게 됩니다.즉, 객체가 생성되기 전에 final 필드를 초기화하기 위한 과정에서 또 다른 객체 생성이 발생하므로 무한 루프에 빠지..
Spring
HTTP 메서드 매핑 PathVariable(경로 변수)URL 경로에 동일한 패턴의 가변 값을 받아서 처리하기 위할 때 사용/** * PathVariable 사용 * 변수명이 같으면 생략 가능 * @PathVariable("userId") String userId -> @PathVariable String userId */@GetMapping("/mapping/{userId}")public String mappingPath(@PathVariable("userId") String data) { log.info("mappingPath userId={}", data); return "ok";} 특정 조건 매핑파라미터헤더미디어 타입 조건 매핑 - HTTP 요청 Content-Type, consume미디어 타입..
FrontController vs 스프링 MVCFrontController => DispatcherServlethandlerMappingMap => HandlerMappingMyHandlerAdatper => HandlerMappingModelView => ModelAndViewviewResolver => ViewResolverMyView => View DispatcherServlet부모 클래스에서 HttpServlet을 상속 받아서 사용, 서블릿으로 동작DispatcherServlet => FrameworkServlet => HttpServletBean => HttpServlet스프링 부트는 DispatcherServlet을 서블릿으로 자동으로 등록모든 경로(urlPatterns="/")에 대해서 매..
V1 구조public class MemberControllerV1 implements ControllerV1 { @Override public void process(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException { String viewPath = "/WEB-INF/views/new-form.jsp"; RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath); dispatcher.forward(request, response); }}@WebServlet(name = "frontControllerServlet..
개요너무 많은 역할하나의 서블릿이나 JSP만으로 비즈니스 로직과 뷰 렌더링까지 모두 처리하는 문제점너무 많은 역할 담당유지보수 어려워짐 변경의 라이프 사이클내부와 외부의 라이프 사이클이 다름UI 수정과 비즈니스 로직 수정은 각각 다르게 발생할 가능성이 매우 높음대부분 서로 영향을 주지 않는다분리되어 있기 때문에 함께 관리하는 것은 좋지 않다 기능 특화뷰 테플릿은 화면을 렌더링 하는데 최적화 되어 있기 때문에 분리하여 담당하는 것이 효과적이다 Model View Controller컨트롤러HTTP 요청을 받아서 파라미터를 검증하고, 비즈니스 로직을 실행한다. 그리고 뷰에 전달할 결과 데이터를 조회해서 모델에 담는다모델뷰에 출력할 데이터를 담아둔다.뷰가 필요한 데이터를 모두 모델에 담아서 전달해주기에 뷰는 비..
서블릿 등록@WebServlet 서블릿 어노테이션name : 서블릿 이름urlPatterns : URL 매핑@WebServlet(name = "hello", urlPatterns = "/hello")public class Hello extend HttpServlet {} HTTP 요청 메시지 로그 propertieslogging.level.org.apache.coyote.http11=debug WAS의 요청 응답 구조 HttpServletRequest개발자가 HTTP 요청 메시지를 편리하게 사용할 수 있도록 HTTP 요청 메시지를 파싱한 것을 담는 객체HTTP 요청 메시지를 편리하게 조회 할 수 있게 해줌 임시 저장소 기능저장 : request.setAttribute(name, value)조회 : re..
request 스코프@Controller@RequiredArgsConstructorpublic class LogDemoController { private final LogDemoService logDemoService; private final MyLogger myLogger; @RequestMapping("log-demo") @ResponseBody public String logDemo(HttpServletRequest request) { String requestURL = request.getRequestURL().toString(); myLogger.setRequestURL(requestURL); myLogger.log("controller test"); logDem..
빈 스코프빈이 존재할 수 있는 범위싱글톤기본 스코프, 스프링 컨테이너의 시작과 종료까지 유지되는 가장 넓은 범위의 스코프프로토타입스프링 컨테이너는 프로토타입 빈의 생성과 의존관계 주입까지만 관여하고더는 관리하지 않는 매우 짧은 범위의 스코프웹 관련 스코프request: 웹 요청이 들어오고 나갈때 까지 유지되는 스코프session: 웹 세션이 생성되고 종료될 때 까지 유지되는 스코프application: 웹의 서블릿 컨텍스트와 같은 범위로 유지되는 스코프 프로토타입 스코프프로토타입 스코프를 스프링 컨테이너에 조회하면 스프링 컨테이너는 항상 새로운 인스턴스를 생성해서 반환한다요청 => 프로토타입 빈을 생성, 필요한 의존관계를 주입반환 => 생성한 프로토타입 빈을 클라이언트에 반환 / 같은 요청이 오면 항상 ..
스프링 빈의 이벤트 라이프사이클스프링 컨테이너 생성스프링 빈 생성의존관계 주입초기화 콜백 : 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출사용소멸전 콜백 : 빈이 소멸되기 직전에 호출스프링 종료의존관계 주입이 완료 되기 전에 초기화 작업을 하면 적용이 안됌@Bean 등록시 ~.setxx(xx) 이런거 해주면 안들어간다는 소리 @PostContruct / @PreDestroy()정상적으로 값 대입 후 출력 완료public class NetworkClient { private String url; public NetworkClient() { System.out.println("생성자 호출, url = " + url); } public void setUrl(String url) { this.u..
의존관계 주입생성자 주입생성자 호출 시점에 딱 1번만 호출 되는 것이 보장불변, 필수 의존관계에 사용final 키워드!!!!생성자에서 혹시라도 값이 설정되지 않는 오류를 컴파일 시점에 막아준다컴파일 오류는 세상에서 가장 빠르고 좋은 오류!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!@Componentpublic class OrderServiceImpl implements OrderService { private final UserRepository userRepository; private final DiscounPolicy discountPolicy; @Autowired public OrderServiceImpl(UserRepository userRe..
ComponentScan@Configuration@ComponentScan( basePackages = "hello.core", // 탐색할 패키지의 시작 위치를 지정 excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = Configuration.class)))public class AutoAppConfig {}// ex) filter로 Configuration을 걸면 @Configuration을 가지고 있는 다른 클래스들을 빼고 등록@ComponentRepositoryServiceRateDiscountPolicy...// @Component로 스캔할 대상을 등록함빈 이름 기본 전략: MemberServiceImpl 클래스 => member..
스프링 DI 컨테이너(싱글톤 컨테이너)스프링 컨테이너를 통해 사용자의 요청이 올 때 마다 객체를 생성하는 것이 아니라, 이미 만들어진 객체를 공유해서 효율적으로 재사용할 수 있게 됌 싱글톤 방식의 주의점여러 클라이언트가 하나의 같은 객체 인스턴스를 공유하기 때문에 싱글톤 객체는 상태를 유지하게 설계하면 안됌무상태로 설계해야 함특정 클라이언트에 의존적인 필드가 있으면 안됌특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안됌가급적 읽기만 가능해야 함필드 대신에 자바에서 공유되지 않는 지역변수, 파라미터 등을 사용해야 함스프링 빈의 필드에 공유 값을 설정하면 정말 큰 장애가 발생할 수 있음public class StatefulService { private int price; // 상태를 유지하는 필드 ..