안녕하세요. 강의를 잘 듣고 있습니다! 다름이 아니라, Bean의 생명주기 메소드 강의에서 마지막 부분이 HelloController의 applicationContext를 생성자 주입하는 코드로 변경하면서 끝이 납니다. 그런데 DI와 단위 테스트 강의에서 HelloController의 테스트 코드를 작성할 때 보여주시는 HelloController.java의 코드를 보면 applicationContext를 생성자에서 파라미터로 받는 부분이 없어져 있습니다. 2개의 강의 사이에서 applicationContext를 파라미터로 받는 코드를 리팩토링하는 부분을 설명해주시는 부분이 제가 찾기에는 보이지 않아서... 혹시 보충 설명을 해주시면 감사하겠습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 헷갈리는 부분이 있어 질문드립니다. em.persist(member) 를 하게 되면 DB에 저장이 바로 되는건지, 영속성 컨텍스트에만 저장이 되는건지 궁금합니다. 그리고 DB 연결이 안되어 있는 상황에서 em.persist(member) 를 하게 된다면 어디에 저장이 되는 건지도 헷갈립니다.
안녕하세요. 강의 너무 재미있게 잘 듣고 있습니다. 강의 듣다가 클래스 로더를 가져오는 부분에서 의문점이 있는데요(사실 이전부터 개념이 명확하지 않아 어려움이 있었습니다) MyOnClassCondition 만들면서 context.getClassLoader() 이렇게 클래스 로더를 가져왔는데 이렇게 가져오는 것과 this.getClass().getClassLoader() 이렇게 가져오는 것이 어떠한 차이가 있는지 궁금합니다. 둘다 동작은 잘 되거든요. 스프링 부트와 크게 관련된건 아니라고 생각들지만 인터넷 글을 봐도 명확하게 이해가 잘 안되서 초고수 토비님께 문의드립니다. 명강의 감사합니다.!!
cannot acess 에러가 발생하는데, 실제, 코드를 돌리면 컴파일 및 런타임 에러 없이 동작합니다. Access 에러 길래, 접근 제어자 문제로 판단하였으나, 전부 Public 이라 딱히 문제도 없는것 같은데, 저만 그런건지 궁금합니다. registerBean 에서도 해당 클래스를 불러오기 때문에, 여기서도 에러가 뜬다면 이해하겠으나.. 해당 부분은 문제없고.. 밑에서만 떠서... 궁금합니다 [참고로, 실행하면 컴파일 에러 없이 실행 되고... IDE 상에서는 에러로 계속 남아 있습니다. ] package com.example.helloboot; import org.apache.catalina.startup.Tomcat; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.context.support.GenericApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class HellobootApplication { public static void main(String[] args) { // Spring Container 생성 Context 가 Container 임 // 컨테이너 생성 GenericApplicationContext applicationContext = new GenericApplicationContext(); // 오브젝트 (빈) 등록 applicationContext.registerBean(HelloController.class); // 오브젝트 생성 요청 applicationContext.refresh(); // [Step 1] Servlet 컨테이너 생성 // Factory 생성과 설정 작업등을 대신 해주는 대상 TomcatServletWebServerFactory serverFactory = new TomcatServletWebServerFactory(); WebServer webServer = serverFactory.getWebServer(servletContext -> { servletContext.addServlet("frontcontroller", new HttpServlet() { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 인증, 보안 , 다국어, 공통 기능 등 처리 if (req.getRequestURI().equals("/hello") && req.getMethod().equals(HttpMethod.GET.name())) { String name = req.getParameter("name"); // binding 데이터를 처리하는 오브젝트에 데이터를 넘기는 것 HelloController helloController = applicationContext.getBean(HelloController.class); String ret = helloController.hello(name); resp.setContentType(MediaType.TEXT_PLAIN_VALUE); resp.getWriter().println(ret); } else { resp.setStatus(HttpStatus.NOT_FOUND.value()); } } }).addMapping("/*"); }); webServer.start(); } }
현재 챕터07 접근제어자(후반전) 까지 강의를 들었고 퀴즈도 다 풀어냈습니다. 그런데 public, class, static, void 등을 조합해서 코드 앞부분에 쓰는데 언제 어떻게 왜 조합해서 저것들을 붙이는 건지 정확한 개념을 잘 모르겠습니다. 이럴때는 강의를 다시 돌려보며 개념을 알고 가야하나요? 아니면 그냥 강의 쭉 들으면서 서서히 익히면 되는건가요 유튜브 영상으로 9시간 다 보고 인프런 결제했는데 갑자기 진행속도가 너무 빨라진 듯한 느낌이 듭니다. 유튜브 기초 9시간때는 이해하면서 잘 들었는데 지금은 코드 따라적기 바쁘네요ㅠㅠ
이 부분에서 em.persist(team) 을 한 후 회원 저장 구현을 한 후 em.persist(member) 를 했는데 회원 구현 이후에 em.persist(team) 를 해도 되나요? 회원 저장 구현 전에 em.persist(team) 를 해야 하는 이유가 있나요?
if (factoryCam instanceof FactoryCam) { (FactoryCam)factoryCam; } 이 구문에 혼동이 생겨서 질문드립니다! if 안에 조건문의 내용이 " factoryCam 이 FactoryCam 클래스의 인스턴스가 맞다면 " 이라고 설명을 해주셨는데요 (8분 27초경) 만약에 factoryCam 이 FactoryCam 클래스의 인스턴스가 맞다면 형변환이 필요 없는거 아닌가요? 또 헷갈린거 하나 더 문의드립니다. 다형성에 대한 예시를 위해 작성해주셨던 코드 내용인데요. Camera factorycCam = new FactoryCam(); 만약에 위 코드로 작성한게 부모클래스인 " Camera" 로 객체를 생성한 거라면, factoryCam 의 참조 클래스는 Camera 인 것 같은데요. (그러니까 FatoryCam 의 인스턴스 메서드를 불러왔을 때 에러가 나는 것으로 보이구요.) 근데 이 설명과 "factoryCam instanceof FactoryCam" 이 구문이 " factoryCam 이 FactoryCam 클래스의 인스턴스가 맞다면 " 이라고 설명을 해주시니 상충되는 내용이 아닌가 싶어 혼동이 옵니다. 내용 요약 factoryCam 은 부모 클래스로 만들어진 객체라서 FactoryCam 의 인스턴스 메서드를 사용할 수가 없다고 설명을 해주셨습니다! 헌데 if 조건문은 "factoryCam 이 FactoryCam 클래스에 포함되어 있다면 " 이라고 설명해주신 부분이 상충되지 않나 하여 헷갈립니다. 그리고 2번에 내용처럼 만약 factoryCam 이 FactoryCam 클래스에 이미 포함되어 있다면, 굳이 형변환을 하지 않고도 detectFire 메서드를 호출할 수 있어야 하지 않는지..? 제가 개념을 잘못 이해하고 있을 것 같은데, 혹시 설명을 좀 부탁드려도 될까요? 이 부분에 자꾸 혼동이 생겨서 다음으로 넘어가기가 어렵네요 🤣 ps. 이전에 강사님 파이썬 강의로 난생 처음 태어나 클래스란 개념을 이해했던 수강생으로써, 이번 자바편도 개인적으로 큰 도움되고 있습니다. 감사합니다!
강의에서 말씀하신대로, 단위테스트 혹은 통합테스트와 같은 용어들이 단어가 느슨하게 정의되어 있어 블로그, 책, 강의마다 설명들이 다 달라서 면접 같은 곳에서 질문을 받으면 매우 곤란한데요. 단위 테스트, 통합 테스트 범위? 정의? 같은 것에 대한 토비님의 개인적인 의견 혹은 기준이 궁금합니다.
안녕하세요 토비님! 강의를 듣는 중에, 여러개의 데코레이터를 우선순위를 정하는 방법 말고 원하는 상황에 맞게 주입이 되도록 처리하는 방식에 대해 말씀해주셨는데, 해당 방법에 대해 좀더 자세하게 알고 싶어져서 사용하는 예제 코드를 구글링 해보았지만 못찾겠어서 질문 올립니다.
[질문 내용] 안녕하세요. 수강생 김땡땡이라고 합니다. 추가로 작성해주신 Spring 3.0 버전 설정을 적용해서 build.gradle을 작성했는데 아래와 같은 에러가 발생하면서 테스트 에러가 발생합니다. 먼저 강의내용과 수업자료를 통해서 Springboot 3.0 이상 버전에서 설정해야되는 부분들을 추가했습니다. javax관련 오류는 뜨지 않습니다. 하지만 다른 문제가 생겼는데요.. gradle >other >compileQuerydsl 을 실행하면, 문제점이 있습니다. compileQuerydsl을 통해서 생성되는 Q Class는 build 경로에만 생기고 src/main에는 생성이 되지 않는다. <build 경로 아래에는 성공적으로 Qclass 가 생성되었습니다.> 하지만 src/main아래에는 생성되지 않았네요.. 그래도 build 경로아래에 QClass가 생성되어있으니 간단한 Test는 될 것 같아서 수업 내용을 따라서 작성하고 실행해봤는데. 위와 같은 에러가 발생했습니다. Qclass를 찾지못해 발생하는 오류같은데.. 왜 이런 현상이 생기는지 모르겠습니다. 강사님과 똑같이 작성했는데.. 단순 버전 문제일까요? 이런경우엔 gradle 버전도 상관이 있는건가요? 현재 사용하는 gradle 버전은 확인해보니 7.6입니다. 검색을 많이 해봐도 해결방안이 나오질 않습니다. 도움 부탁드립니다. =======================저의 build.gradle 설정======================== plugins { id 'java' id 'org.springframework.boot' version '3.0.2' id 'io.spring.dependency-management' version '1.1.0' id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } group = 'study' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' // Querydsl 추가 implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" } tasks.named('test') { useJUnitPlatform() } //querydsl 추가 시작 def querydslDir = "$buildDir/generated/querydsl" querydsl { jpa = true querydslSourcesDir = querydslDir } sourceSets { main.java.srcDir querydslDir } configurations { querydsl.extendsFrom compileClasspath } compileQuerydsl { options.annotationProcessorPath = configurations.querydsl } //querydsl 추가 끝 ======================= Hello Entity ============================= package study.querydsl.entity; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import lombok.Getter; import lombok.Setter; @Entity @Getter @Setter public class Hello { @Id @GeneratedValue private Long id; }
======================================== [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] @GetMapping("hello-string") @ResponseBody public String helloString(@RequestParam("name") String name1){ return "hello"+name1; } 위와 같은 코드와 url에서 localhost:8080/hello-string?name=springboot를 입력받았을 때 파라미터 name은 key값으로서 value값인name1과 바인딩 되어 name1에 springboot를 저장 하기위한 용도로 사용되는 건가요? 다른 시각으로 name1을 key값로 springboot를 value값 생각해도 되는건가요? name - name1 - springboot (key) - (value) ................(key) - (value) 즉, 이렇게 이해해도 되는건가요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예 [질문 내용] 여기에 질문 내용을 남겨주세요. 주문 목록 검색, 취소 강의 2분 20초 즈음에 함수위임 정도의 간단한 행동은 컨트롤러에서 직접 호출하는 것도 고려해도 괜찮다라고 하셨는데, 이는 즉 컨트롤러가 레포지토리를 바로 의존하는 상황이여도 상황에 따라서는 괜찮다고 이해하여도 괜찮을까요 ?