묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
DAO와 REPOSITORY의 차이점...
안녕하세요 항상 좋은 강의 제공해주셔서 감사드립니다. 강의를 듣다보니 dao와 repository의 차이점이 궁금해서 질문을 남깁니다. 검색해보니 dao는 data persistence의 추상화 , repository는 collection of objects의 추상화라고 하는데, 사실상 둘의 기능은 비슷하다고 생각합니다. 하지만 둘의 차이를 명확하게 알고 싶어 질문드립니다. 혹시 mybatis를 사용할때 sql과 매핑할때 dao를 사용하고, repository는 엔티티를 영속성 컨텍스트에 영속화 시킬때 사용하는건가요???
-
미해결스프링 핵심 원리 - 기본편
getBeanDefinition
ApplicationContext말고 구체화된 클래스(예: AnnotationConfigApplicationContext)를 쓰는 이유가 getBeanDefinition을 쓸 수 없어서라고 하셨는데, 그 이유가 무엇인가요? AnnotationConfigApplicationContext가 구현한 여러가지 인터페이스중, ApplicationContext가 아닌 다른 인터페이스가 getBeanDefinition이라는 메서드를 제공하기 때문이라는 말씀이신가요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
HTTP API와 자바스크립트 질문
질문에 앞서 제가 자바스크립트를 잘 모르고 HTML, CSS만 대충 알고 있습니다. 참고하시고 답변 부탁드릴게요. (질문) HTTP API는 HTML이 아닌 데이터를 주고 받기 때문에 "웹 브라우저"가 아닌 "웹 클라이언트 자바스크립트"가 데이터를 처리하고 사용자에게 보여준다고 하셨습니다. 여기에서 웹 클라이언트 자바스크립트가 구체적으로 뭔지 모르겠습니다. 자바 스크립트라는 프로그램이 개인 PC마다 설치되어 있는 건지... 조금 더 구체적으로 설명해주시면 감사하겠습니다.
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
CSR에 관해 질문드립니다.
안녕하세요. 항상 좋은 강의 감사드립니다. 제가 백엔드 쪽만 공부하다보니 프론트 쪽에 관해 많이 모르고 있는데요. 1. 강의에서 CSR에 대해서 설명해주신 부분에서 '서버'를 언급해주셨는데, 그 때의 서버는 리액트나 뷰와 같은 프론트단 서버를 의미하는 건가요? 그러면 CSR의 경우는 Spring 서버에 오기 전 클라이언트단 서버에서 이미 처리가 되고, 백단 서버에는 요청이 가지않는 상태를 의미하는건가요? 2. 전체적인 HTTP 흐름이 '클라이언트 -> 클라이언트단 서버 -> Spring 서버 -> DB -> 응답' 순이 맞을까요? 아니면 로직마다 다르게 적용되어 클라이언트 <-> 클라이언트단 서버, 클라이언트 <-> 백단 서버 이런식으로 요청, 응답을 받는건가요? 3. 그리고 제가 백엔드만 공부한 상태로 포트폴리오로 개인프로젝트를 혼자 개발해보려고 하는데요. 강의에서는 서버 사이드 렌더링 기술만 익히면 된다고 하셨는데, CSR 없이 타임리프와 spring으로만 개발해도 괜찮을까요? 백엔드 개발자가 개인프로젝트를 해야하는 할 때 갖춰야할 최소한의 프론트 지식이 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
왜 log.error가아닌 log.info를 사용하나요?
error 메세지의 경우 log.error가 아닌가요?ㅜㅜ 실제 개발할때 이런 에러 로그에 대해서 info를 사용하는지 error혹은 warn을 사용하는지 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
FileNotFoundException 오류
아래 코드를 작성하고 난 후 나는 에러입니다. 강의 내용상으로는 30:47에 작성하신 코드입니다. @ResponseBody@GetMapping("/images/{filename}")public Resource downloadImage(@PathVariable String filename) throws MalformedURLException { return new UrlResource("file:" + fileStore.getFullPath(filename));} 2021-09-23 14:12:09.196 ERROR 2112 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception java.io.FileNotFoundException: URL [file:C:/Users/계정이름/Desktop/study/${imageFile.getStoreFileName()}] cannot be resolved in the file system for checking its content length at org.springframework.core.io.AbstractFileResolvingResource.contentLength(AbstractFileResolvingResource.java:232) ~[spring-core-5.3.9.jar:5.3.9] at org.springframework.http.converter.ResourceHttpMessageConverter.getContentLength(ResourceHttpMessageConverter.java:121) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.http.converter.ResourceHttpMessageConverter.getContentLength(ResourceHttpMessageConverter.java:45) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.http.converter.AbstractHttpMessageConverter.addDefaultHeaders(AbstractHttpMessageConverter.java:260) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:211) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:293) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:183) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1064) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.9.jar:5.3.9] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.9.jar:5.3.9] at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.52.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.9.jar:5.3.9] at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.52.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.9.jar:5.3.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1726) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.52.jar:9.0.52] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] 이런 에러가 납니다. 제가 윈도우 환경이라서 경로를 잘못 설정했을까봐 https://www.inflearn.com/questions/268366 이곳을 참고하여 application.properties 파일을 logging.level.org.apache.coyote.http11=debug file.dir=C:/Users/계정이름/Desktop/study/ 이렇게 작성했는데, 제출 버튼을 누르면 저렇게 오류가 납니다. 위 코드를 주석처리하고 실행해보면 잘 실행이 되는데, 위 코드를 작성하고 실행시키면 저렇게 에러가 나네요. 왜그런지 알 수 있을까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
v1: 엔티티직접노출 방식에 달린 주석 질문
@GetMapping("/api/v1/orders")public List<Order> ordersV1() { List<Order> all = orderRepository.findAll(); for (Order order : all) { order.getMember().getName(); //Lazy 강제 초기화 order.getDelivery().getAddress(); //Lazy 강제 초기환 List<OrderItem> orderItems = order.getOrderItems(); orderItems.stream().forEach(o -> o.getItem().getName()); //Lazy 강제 초기화 } return all;} 첨부된 소스코드를 보면 "트랜잭션 안에서 지연 로딩 필요"라고 v1 메소드에 설명이 있습니다. orderRepository.findAll( ); 의 호출이후 트랜잭션은 종료됐을 텐데 그 이후에 강제 Lazy로딩을 하는 것이 위 주석의 설명과 혼동이 됩니다. 기본편에서 진행을 할 때는 항상 tx.commit( ) 이전에 Lazy로딩을 했기 때문에 트랜잭션 안에서 지연로딩을 한다는 의미를 당연하게 받아드렸지만 웹MVC를 결합하면서 Controller쪽에서 findAll() 호출 후 진행되는 상황은 트랜잭션이 종료된 후이기 때문입니다. 답변부탁드립니다. 감사합니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
return new CreateMemberResponse(id); 필요성
@RestController @RequiredArgsConstructor public class MemberApiController { .. @PostMapping("/api/v1/members") public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member) { Long id = memberService.join(member); return new CreateMemberResponse(id); } @Data static class CreateMemberResponse { private Long id; public CreateMemberResponse(Long id) { this.id = id; } } 일 때, memberService.join(member); 의 반환 값이 엔티티가 아니고 단순히 Long id인 값인데도 return id; 로 안하고 CreateMemberResponse 클래스를 만들어 return new CreateMemberResponse(id); 로 하는 이유는 뭔가요 ? 처음에는 Long id = memberService.join(member); return id; 로 했다가 누군가가 inline으로 합쳐버려서 return memberService.join(member); 으로 만들어 버리면 memberService.join의 반환 값이 수정될 때 컴파일이 안뜨고, api에서 스펙이 바뀌어 오류가 생길 가능성이 있어서 컴파일 단계에서 막아버릴려고 CreateMemberResponse 클래스를 만들어 return new CreateMemberResponse(id); 를 해주는 것일까 생각도 들었는데, inline으로 합쳐버리고 memberService.join의 반환값이 바뀌어도 어차피 @PostMapping("/api/v1/members") public Long saveMemberV1(@RequestBody @Valid Member member) { Long id = memberService.join(member); return id; } 인 상태에서 inline하는 거니까 public Long saveMemberV1(..) {..} 에서 return값이 Long타입이 아니게 바뀌면 컴파일 뜰 것 같아서 그것도 아닌가 싶기도 하고 .. 유지보수할 때, 추적하기 쉬우려고 그러는 건가 싶기도 하고 .. 갑자기 든 생각인데, 일반적으로는 단순히 id만 반환할 일이 없으니 일반적인 케이스를 생각해 만드신 건가 싶기도 하고.. 이 케이스만 예외적으로 Long으로 써도 가능한 건지 궁금합니다 :]
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
FrontControllerServletV3의 기능중 이해가 안되는 부분이 있습니다.
Map<String, String> paramMap = createParamMap(request);ModelView mv = controller.process(paramMap);String viewName = mv.getViewName();MyView view = viewResolver(viewName);view.render(mv.getModel(), request, response); 안녕하세요 위 소스에 대한 내용이 궁금해서 문의 드립니다. 제가 이해한대로 우선 설명을 드리면.. Map<String, String> paramMap = createParamMap(request); request에서 받아온 값들을 Key, Value 형식으로 paramMap에 담아주는 역할을 함.(key: username, value : 34)이런식으로 ModelView mv = controller.process(paramMap); 주소값에 따라 value에 저장되어있는 컨트롤러(ex> MemberListControllerV3에서 저장한 viewName을 반환해준다(안에 값이 있으면 같이 보내준다(컨트롤러의 기능에 따라 저장된 값들) String viewName = mv.getViewName(); 이 부분이 위의 mv에 저장되어있던 값들중 viewName값(save-resultemd)을 가져온다. MyView view = viewResolver(viewName); 이곳에서 전체적인 경로(/WEB-INF/views/ + viewName + .jsp)를 조합해서 리턴할 풀 경로를 만들어준다. view.render(mv.getModel(), request, response); 이 부분이 제일 이해가 안가는 부분입니다. 모델에 있는 값들을 꺼내서 request에 담아서 jsp쪽으로 보내주는 내용인데.. render를 할 때 mv.getModel() 이 값에 모델 정보들을 넘겨주는데 getModel이라는 정보가 위에서 controller.process(paramMap)의 컨트롤러에서 process메소드를 실행해서 넣어준 mv.getModel().put() 값을 말하는게 맞는거죠? 그렇게 만들어준 값들을 view 화면에 넘겨주기 위해서 render를 할 때 mv.getModel정보를 같이 render에 넘겨줘서 render에서는 해당 값들을 뽑아서 request값에 setAttribute로 key, value로 넣어줘야 jsp 파일에서 쉽게 사용을 할 수 있기 때문에 render에서 request에 담아서 화면단으로 넘겨주는게 맞는거죠?? 정리가 안되는 부분이 있어서 문의글을 적으면서 차근차근 글을 적다보니 대략적으로 이런식으로 흘러가는거구나.. 하고 감이 잡히는 것 같은데 제가 이해하고 있는 부분이 맞는건지, 아니면 놓치는 부분이 있는지 궁금합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
init은 누가 호출하는 건가요..?
@RequestMapping("/basic/items") 여기로 url이 들어오면, get으로 바로 @GetMappingpublic String items(Model model) { 이쪽으로 들어오고, return으로 html을 반환하지 않나요? 그런데 상품이 등록 되어 있던데.. @PostConstructpublic void init() { itemRepository.save(new Item("testA", 10000, 10)); itemRepository.save(new Item("testB", 20000, 20));} 이 init은 누가 호출하는 것인지 궁금합니다.
-
미해결실전! 스프링 데이터 JPA
DTO로 조회시 DTO의 조회 위치는 어디가 되면 좋을까요..?
안녕하세요 강의를 보던 도중 의문이 생겨서 질문남깁니다. Layerd Architecture 에서 Controller, Service, Repository로 역할을 구분해서 레이어당 커플링을 줄이도록 하고 있는 알고 있습니다. 그런데 DTO 의 사용위치 (해당 DTO는 사용자 API)에 대해 궁금한 점이 있습니다. JPA에서 DTO로 조회하면 편하게 데이터를 가져 올수 있는데 해당 DTO가 서비스 혹은 Application Layer에 커플링이 생기는데 이럴 경우는 어떻게 해결해야 될까요..? DTO 자체를 Service DTO, 와 Controller DTO로 분리하여 컨버팅을 해주어야 되는지 아니면 Controller 에서 Repository 를 직접 사용해도 되는 예외상황을 고려해야될지가 고민입니다. 아니면 엔티티를 조회한후 필요한 부분만 DTO로 변환을 하는지 그것도 아니면 Object 객체로 조회한후 Object 안에서 데이터를 추출하는지 어떤 방법을 사용하시는지가 궁금합니다. 보통 이런 경우에는 어떻게 처리하는게 효율적인 방법일까요..? 시스템 개발을 하다가 서비스로 커리어 전환을 하고 있는데 김영한님 강의가 너무 재밌어서 계속 찾아보게 되네요 ㅎ
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
@Controller , @RequestMapping
안녕하십니까 영한님 ! 제가 잘 이해하고 있는지 , 아닌지에 대해 여쭙고자 질문을 남깁니다. @Controller를 통해 스프링 빈으로 해당 클레스가 등록이 되고 , @RequestMapping에 담긴 논리URL 통해 클라이언트가 전송한 URL과 매칭 여부를 판단해 ( getHandler() ) @Cotroller로 등록된 객체를 반환하여, 그에 맞는 어댑터를 통해 해당되는 Controller을 실행하는게 맞을까요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Error
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: org.h2.Driver 이런 코드가 뜨면서 계속 오류가 발생해서 test를 해볼 수가 없습니다. 무엇이 문제인가요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
종속성 순환에러 질문드립니다....
선생님 안녕하세요! 꾸준히 걸어가고있는 코린입니다.. 혹시 @Component@Transactional@RequiredArgsConstructorstatic class InitService { 이 부분에서 static이 아닌 private으로 봐꿔보면 종속성 순환에러에 걸리는데 static일때는 메모리를 공유하고 private일때는 공유 하지않아서 생기는 문제인가요?
-
미해결스프링 핵심 원리 - 기본편
의존관계 주입 시점
IoC, DI, 그리고 커네이너 강의 질문입니다. DI 설명 중 주입은 런타임 시라고 되어있는데 컴파일 시점 아닌가요?? 컴파일 시점에 이미 다 주입이 되고, 런타임에는 주입된 것을 사용한다고 생각하는데 이해가 좀 안되어서요 ㅜ.ㅜ 컴파일 시점에는 주입은 일어나지 않고, 스프링을 빌드(런타임)할 때, 주입이 일어난다는 의미 일까요??
-
미해결스프링 핵심 원리 - 기본편
혹시 지금까지 제가 이해한 내용이 올바른건지 궁금합니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://docs.google.com/document/d/1j0jcJ9EoXMGzwAA2H0b9TOvRtpwlxI5Dtn3sRtuXQas/edit#heading=h.w2tomwsznga7)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://docs.google.com/document/d/1xCQKit-1V6l6ObeCe49St33RHPzLF_P_c3o7aSDTKs0/edit#heading=h.7dhnp46ven0v)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] 💡 DI (Dependency Injection) - 의존관계 주입 의존하는 객체를 직접 생성하는 것이 아니라, 외부에서 생성한 후 주입하는 것. 3가지 조건이 필요 클래스 모델이나 코드에는 런타임(실행) 시점의 의존관계가 드러나지 않는다. (= 정적인 클래스 의존관계가 아니다)(= 동적인 객체 인스턴스 의존관계이다) => 인터페이스에만 의존하고 있어야 한다 런타임 시점의 의존관계는 외부에서 결정한다 외부에서 실제 구현 객체(사용할 오브젝트에 대한 레퍼런스)를 생성하고 클라이언트(사용할 오브젝트)에 전달(주입)함으로써 의존관계가 연결되는 것이다 예를 들어 private Car myCar = new 벤츠(); => Car가 인터페이스고 벤츠가 구현 객체라면, 런타임 이전에, 즉 코드상으로 벤츠 클래스를 의존하는 것을 알 수 있다 private Car myCar; => 이러면 Car에 대해 무슨 차가 들어올지 알 수 없다.(런타임 시점의 의존관계가 드러나지 않으므로) => 즉 이렇게 인터페이스에만 의존하고 의존관계 주입이 발생할 수 있다. 💡 IoC (Inversion of Control) - 제어의 역전 프로그램의 제어 흐름(ex:메소드나 객체의 호출작업)을 개발자가 결정하는 것이 아니라, 외부에서 결정(관리)하는 것. 즉 객체를 개발자가 Member member = new Member(); 이런식으로 만드는 것이 아니라, 스프링이 스스로 객체를 생성해서, 필요한 곳에 사용할 수 있게 해줌! 1 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class); cs 위 코드 단 하나만 실행했을 뿐인데, 우리는 ac.getBean을 통해, 원하는 객체를 사용할 수 있음!!!!! 참고로 DI도 제어의 역전에 포함되는 기술이며, IoC는 좀더 광범위하게 쓰인다! 🧾 부분 정리 스프링은 IoC, DI와 같은 기술을 사용함으로써 자바만으로는 DIP(의존관계 역전 원칙)와 OCP(계방-폐쇠 원칙)을 지켜가며 객체지향적으로 설계하는데 어려움이 있었는데, 이를 해결. 즉 스프링을 사용하면 좋은 객체 지향 애플리케이션을 개발하기 편해지며, 스프링은 이를 도와주는 프레임워크. 스프링이 좋은 객체 지향 애플리케이션을 개발하는데 도움을 주는 프레임워크인 것 처럼, 스프링 부트는 스프링의 기술들을 좀 더 편리하게 사용하는데 도움을 주는 프레임워크. 제가 정리한 내용들인데, 혹시 맞게 이해한건지요.. 너무 어려워서 여러차례 강의 반복하여 들으며 정리했습니다
-
미해결스프링 핵심 원리 - 기본편
@Component는 구현체에만 붙인다?
인터페이스에는 안붙이고 구현체에만 @Component를 붙이는 이유는뭔가요?
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
이 강의에 대한 질문은 아니지만 질문이 있습니다..
안녕하세요 영한 선생님 ! 저는 강의를 듣고있는 선생님의 팬입니다. 다름이 아니라 선생님의 강의력에 이해가 쏙쏙 되고 뿌듯해하며 하루하루 코딩하며 살아가고 있습니다. 하지만 요즘 문득 이런 생각이 자주 듭니다. '내가 저 코드를 혼자 생각하면서 짤 수 있을까?' 라는 생각이요. 어떠한 원리로 동작하는지 머릿속으로는 알겠고 연결이 되는데 혼자서 코딩을 하려면 어디부터 작성해야할지 막막합니다. 이러한 부분은 어떻게 해야 기를 수 있을까요?
-
미해결스프링 핵심 원리 - 기본편
rateDiscountPolicy를 DiscountPolicy타입으로하는게 좋다
TestConfig에서 rateDiscountPolicy이 DiscountPolicy타입인데 다른데서 의존할때도 DiscountPolicy에 의존하고 있으니까 DiscountPolicy타입으로 하는게 좋다라고 하셨는데 그게 무슨말인지 잘 모르겠어요.. 예를들어서 설명해주실 수 있나요....?
-
해결됨스프링과 JPA 기반 웹 애플리케이션 개발
프로필 수정 처리와 그 외 개인적인 질문드립니다.
안녕하세요, 먼저 좋은 강의 만들어주셔서 감사드립니다. 해당 강의 '프로필 수정 처리' 학습을 진행하던 중 궁금한 사항이 생겨 질문드립니다. 먼저 강의 내용에서 처럼 POST 방식으로 프로필 수정 요청을 하는 경우 @PostMapping("{URL}") 어노테이션이 설정된 메소드가 실행이 되면서 DB의 정보와 Account 객체가 업데이트 되고, 여기서 Account 객체는 세션에 담긴 객체이지만 '준영속성(detached)' 상태로 AccountService.updateProfile(Account accoutn, Profile profile) 메소드를 통해 Merge를 하는 과정을 확인할 수 있었습니다. 다만, 여기서 궁금한 점은 1. 프로필이 수정되기 전 세션에 설정된 Account 객체는 로그인을 통해 SecurityContext에 저장된 User(Principal, 인증된 사용자 정보)와 동일하겠지만, 프로필 수정 후에는 세션의 Account 객체와 User는 서로 다른 상태가 되는게 맞을까요? 만약, 그렇다면 프로필 수정 후 User 정보도 Account 정보와 동일하게 맞추려면 어떤 방법이 있는지 궁금합니다. 2. [개인적인 질문] 만약, 관리자 페이지가 존재해서 사용자가 애플리케이션을 이용하고 있는 중에 관리자가 회원의 정보를 변경하는 경우 사용자는 자신의 정보가 변경이 되었는지 알 수 있는 방법이 있을까요? - 사용자 측면에서 세션의 Account는 계속해서 관리자가 수정하기 전의 자신의 정보만을 바라보고 있을 것 같다라는 생각이 들어서 질문을 남겨봅니다. 글이 길어 졌네요. 답변 미리 감사드립니다.