묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 핵심 원리 - 고급편
구체 클래스 기반 프록시 컨트롤러
강의에서는 실제 객체 Controller를 컴포넌트 스캔의 대상으로 지정하지 않았는데 자바 일정 버전 이상부터는 Controller 객체는 @Controller를 붙여야된다고 수정되어 있더라고요 근데 그러면 강의와 달리 Controller 실제 클래스를 스프링빈에 등록하고 그걸 상속받은 proxy객체도 등록했을 때, 똑같은 경로로 mapping이 오면 어떻게 되나요? 만약 문제가 생긴다면 어떻게 해결해야하나요?
-
해결됨C개발자를 위한 최소한의 C++
빈 포인터에 멤버함수 호출
class A{public:int foo(int num) { return num; }};int main(){A* a = nullptr;int pa = a->foo(10);return 0;}이 코드를 실행하면 문제가 나지 않았습니다. 멤버 함수 호출이라는 것이 결국에 함수에 this포인터만 넣어주는 형태이기 멤버를 건드리지 않는 이상 런타임상에서 크래시가 나지 않는 걸로 생각은 하는데 이 생각이 맞을까요?
-
미해결TS/JS 디자인 패턴 with Canvas: 제로초에게 제대로 배우기
팩토리 메서드에 대해서 궁금증이 생겨서 질문드려봅니다!
심플 팩토리에서 chrome, safari 등등 if문을 통해서 브라우저환경에 맞는 그림판 인스턴스를 가져올 수 있도록 한 코드가 있었는데, 팩토리 메서드가 그 역할을 대신한다고 이해했습니다. 궁금한점은 결국 크롬이든 사파리든 브라우저환경을 알아내서 main함수에 넘겨줄 수 있어야하는데 그 분기는 어디서 해야하는걸까요?function clientCode(creator: Creator) { creator.someOperation() } clientCode(new ConcreteCreator1())아래의 코드라면 new ConcreteCreator1()를 판단할 수 있는 조건 분기를 결국 어디서는 해야하지 않는가에 대한 고민입니다!
-
미해결스프링 핵심 원리 - 고급편
스프링부트 Rest API 서버 구축 시
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]스프링부트 Rest API 서버를 개발할 때 파라미터에 사용되는 어노테이션과 타입을 체크하는 공통 모듈이 필요한가요? 예를 들면@RequestParam Map<String, Object>@RequestBody xxxDTO@PathVariable 피리미티어 타입 또는 레퍼런스 타입만 허용한다. 이런 요구사항이 많나요? 아니면 요구사항이 없더라도 구현하는것이 맞나요? 만약 구현한다면 AOP + HandlerMethodArgumentResolver를 이용하면 될까요?질문이 많아 죄송합니다
-
미해결스프링 핵심 원리 - 고급편
쓰레드 로컬 관련 질문 있습니다.
private void syncTraceId() { TraceId traceId = traceIdHolder.get(); if (traceId == null) { traceIdHolder.set(new TraceId()); } else { traceIdHolder.set(traceId.createNextId()); } } private void syncTraceId() { if (traceIdHolder.get() == null) { traceIdHolder.set(new TraceId()); } else { traceIdHolder.set(traceIdHolder.get().createNextId()); } }강의 중에는 위 쪽처럼 코드를 작성해주셨는데아래에 작성한 코드 처럼 TraceId 객체를 바로 get()으로 가져오지 않고, 별도의 traceId를 만들어 사용하신 이유가 궁금합니다.traceIdHolder가 ThreadLoacl<TraceId> 타입인데 traceIdHolder.set(new TraceId()); 로 값 변경은 바로 하시는데 값을 가져오는 건 다른 방식인 것 같아서 궁금합니다~
-
미해결TS/JS 디자인 패턴 with Canvas: 제로초에게 제대로 배우기
.
.
-
미해결TS/JS 디자인 패턴 with Canvas: 제로초에게 제대로 배우기
[섹션1/사전에 알아두면 좋은 TS/JS 지식]영상 재생 관련 질문 드립니다.
현재 [섹션 1/사전에 알아두면 좋은 TS/JS 지식] 영상이 검은 화면에 음성만 재생되는데 확인 부탁드립니다.감사합니다!
-
미해결스프링 핵심 원리 - 고급편
@AfterReturning 설명 중 객체의 변경과 조작의 차이점
강의 18분 40초쯤 @AfterReturning 설명 중 반환되는 객체를 조작할 수는 있으나 변경할 수는 없다라고 말씀하셨는데 조작의 예시로 setter를 들어주시기는 했으나 setter를 통해 값을 변경하는 것도 결국 변경이 아닌가 생각이 들기도 하고 조작과 변경의 차이가 잘 이해되지 않습니다.조작과 변경의 차이를 조금 더 구체적이고 정확한 예시와 의미를 통해 이해시켜주실 수 있으실까요?
-
미해결TS/JS 디자인 패턴 with Canvas: 제로초에게 제대로 배우기
[12강] 선언식 + bind vs arrow function 어떤거 선호하시나요?
class의 메서드는 선언식으로 쓰는걸 좋아하는데bind는 쓰기 싫어서 bind 필요한것만 arrow function 쓰면 클래스 메서드가 선언식이랑 표현식 섞인게 뭔가 일관성이 없어보이더라구요.. (섞어쓰면 나중에 이거 bind 필요한 메서드였나? arrow function으로 했었나? 헷갈릴것같기도 하고?)
-
미해결스프링 핵심 원리 - 고급편
스프링부트 3.0 이슈에 대한 정리
'프록시패턴과 데코레이터패턴.pdf' p.7 하단의 설명을 이해하는데 시간이 많이 걸렸습니다.다른 수강생분들도 참고하실 수 있도록 정리했습니다. 부트3.0버전에서 나타나는 현상위 상황에서 http://localhost:8080/v2/request?itemId=hello 으로 접근하면 아래와 같은 결과가 나옵니다. 수동등록하여 컨트롤러 Bean이 생성됐다 하더라도위 @RequestMapping 만으로 컨트롤러 로 '인식' 할 수 없음 (부트 3.0부터) 개선 1 (부트3.0)@RequestMapping 과 @ResponseBody ==> @RestController 로 교체시도이렇게 만들면 컨트롤러 로 '인식'할 수 있다.하지만 아래처럼 빈충돌로 애플리케이션 구동자체가 안된다.(@RequestMapping 을 쓰던 이전에는 컴포넌트 스캔이 대상이 아니여서 자동구성 빈이 생성되지 않았고오직 수동구성 빈만 생성됐음)(@RestController로 변경하면서 컨트롤러로 인식하게 됐지만자동구성으로 빈이 등록돼버리고 , 수동구성 빈 등록으로 덮어쓰기를 시도하려하지만 스프링부트는 스프링과 달리 이것을 허용하지 않고 빈충돌 에러를 발생시킴) 위 현상은 v1, v2에서만 발생한다. ('수동구성으로 진행되도록 유도된 예제'에서 불청객으로 자동구성이 발생)반면 v3에서는 발생하지 않는다. (자동구성으로 진행됐기 때문) 따라서 자동구성 대상이 되지 않도록 v3 패키지경로를 컴포넌트스캔지정하여 v1, v2를 스캔대상에서 제외시킨다. 개선 2 (부트3.4)@RequestMapping 과 @ResponseBody ==> @RestController 로 교체이렇게 만들면 컨트롤러 로 인식할 수 있다.위 개선1과 달리 빈충돌없이 애플리케이션 구동이 잘 된다. (빈이 덮어써지게 3.4는 개선됐나보다)
-
미해결스프링 핵심 원리 - 고급편
스프링부트 3.0 이슈에 따른 컴포넌트 스캔 패키지경로
안녕하세요.위 문제에서 패키지를 v3까지 디테일하게 지정을 했는데요.hello.proxy.app.v1 와 hello.proxy.app.v2 관점에서는 어떻게 해석할 수 있는지 궁금합니다. v3는 스프링부트3.0 이전과 이후 달라진 이슈에 영향을 받지 않아보입니다.v1, v2는 어떤 영향을 받는 것인지 알 수 있으면 전체적으로 이해가 될 것같아 질문드립니다.(v1, v2에는 @Controller, @RestController가 없습니다.따라서 빈 자동등록은 부트3.0 이전 이후 모두 동작하지 않을 것으로 기대됩니다)
-
미해결스프링 핵심 원리 - 고급편
스프링로드맵2 스프링기본편의 구성과 사용분리
안녕하세요. 스프링로드맵 2 스프링기본편 강의에서 MemberServiceImpl가 MemoryMemberRepository구현에 강결합되는 상황을 제시해 주셨습니다.이후 아래 그림과 같이 인터페이스 MemberRepository에만 의존하게 끔 설계를 해주셨는데요. 이 때 AppConfig가 등장합니다.public class AppConfig { public MemberService memberService(){ System.out.println("call AppConfig.memberService"); return new MemberServiceImpl(memberRepository()); } public OrderService orderService(){ System.out.println("call AppConfig.orderService"); return new OrderServiceImpl( memberRepository(), discountPolicy()); } }위 코드를 설명하실 땐 구성 이라고 표현하셨는데요. (구성과 실행을 분리) 이것도 전략패턴이라고 말할 수 있나요? 전략패턴에서는 구성대신 조립 이란 설명으로 다르게 표현하셨습니다.
-
해결됨C개발자를 위한 최소한의 C++
순수 가상 클래스 선언과 일반 인트 변수의 선언과 다른가요?
순수 가상 클래스 강의에서 " virtual int getData() const = 0; " 이 코드는 선언만 있다고 말씀하셨습니다.int a = 0; 이라고 코드를 작성하면 선언 및 정의(초기화)가 된것인데 반해, 함수는 단순히 0을 단순대입했다고 해서 정의가 된것은 아니라는 말씀이신가요? 그렇다면 혹시 " virtual int getData() const; " 만으로 선언이 충분한데 " = 0 " 을하는 이유가 있나요? 단순 초기화 인가요?또 한가지, 엄밀히 말하면 int a = 0;은 인트 클래스의 인스턴스 a가 선언 및 정의 된거고, 클래스내 함수(메서드)는 인스턴스를 생성하는 건 아니기에 다른건지 궁금합니다. 항상 좋은 강의 감사드립니다!
-
해결됨C개발자를 위한 최소한의 C++
안녕하세요. 이동의미론에 대해 제가 잘 이해했는지 궁금합니다.
testdata는 class명 입니다. 1. testdata t1 = testdata(1);이 예전에는 임시객체를 생성해서 복사 생성을 했었음. 2. 그런데 그게 비용이 비합리적이니까 move sementic이라는게 나왔고 testdata t1 = std::move(testdata(1));을 사용해서 임시객체를 그냥 t1으로 shallow copy시킴. (C++11)3. 그런데 최근에는 이런 이동의미론 없이 testdata t1 = testdata(1)이라고 써도. 컴파일러가 자동으로 생성자만 호출하는 t1 인스턴스를 생성하는 코드로 평가를 해버림.제가 잘 이해하고 있는지 궁금합니다추가 : Test func(Test src): return src; 해당 함수를 실행 시키면, 값을 반환 할 때, 이동 생성자가 호출되는데반환시는 해당 콜스택이 사라지는 시점이기 때문에 이전까지는 좌측값이였지만,다음 라인에 사라지게 될 src를 우측값 취급을 해서 임시객체를 생성하는것으로 이해했습니다.이렇게 해석해도 괜찮을까요?
-
해결됨스프링 핵심 원리 - 고급편
오타? 및 내용 질문
안녕하세요 선생님 강의 듣다가 질문이 생겨서 글 작성해봅니다 제가 알기로 스프링 2.6 ? 이상에서 순환 참조가 자동으로 비활성 되어서 private final ObjectProvider<CallServiceV2> callServiceProvider; 을 사용해도 lazy 조회가 되지 않는것으로 알고 있습니다 그래서 application.yml 파일에서 이 설정을 true 로 바꿔주거나 test 시 @TestPropertySource(properties = "spring.main.allow-circular-references=true") 이 어노테이션을 추가하려 순환 참조를 활성화 시킨 후에 테스트 해봐야지만 정상 작동 되는걸로 알고 있는데 제가 알고 있는 내용이 다른지 궁금합니다
-
미해결TS/JS 디자인 패턴 with Canvas: 제로초에게 제대로 배우기
싱글톤 강의
싱글통 강의에서 숙제에 대한 답변도 볼 수있는 곳이 있을까요?
-
미해결TS/JS 디자인 패턴 with Canvas: 제로초에게 제대로 배우기
리스코프 치환원칙은 반,공변성과 같은 원리인가요?
class Parents { // 좁은 파라미터 method(name: string, test: string) { // 넓은 반환 타입 return { key: "" }; } } class Child extends Parents { // 넓은 파라미터 override method(name: string) { // 좁은 반환 타입 return { key: "", name: "" }; } } 안녕하세요,리스코프 치환원칙을 보니 반,공변성의 원칙과 같이매개변수는 반공변성을 리턴은 공변성을 가지는 것 같은데, T<child> -> T<parents> 개념이 되는 타입의 정의 원칙을 리스코프 치환 원칙이라 하는 것일까요?
-
미해결스프링 핵심 원리 - 고급편
proxyFactory.setProxyTargetClass(true); 궁금한거 있습니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]proxyFactory.setProxyTargetClass(true);하면 인터페이스가 있어도 CGLIB로 프록시를 만든다고 했는데CGLIB는 클래스를 상속해서 프록시를 만드는 거 아니었나요? 어떻게 인터페이스만 있는데 이걸 CGLIB기술로 프록시를 생성하는거죠
-
미해결스프링 핵심 원리 - 고급편
빈 후처리기에 프록시 객체 질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 강사님훌륭한 강의 항상 잘 보고 있습니다.다름이 아니라, 이번에 빈 후처리기와 프록시 패턴에 대해 질문이 있습니다. 아래와 같이 빈 후처리기에서 A 객체를 A 프록시로 바꿔치기 해서 스프링 빈에 저장하고, A 프록시를 싱글톤으로 관리한다라고 이해했습니다. 이때, 궁금한 부분이A 프록시가 A 객체를 상속받아서, 부가기능인 advisor 기능을 추가한 A 프록시라는 객체를 새롭게 생성해서 스프링 빈으로 등록을 한다라고 이해하면 되는건가요?예를 들어, A 클래스가 A 메소드만 구현한 클래스라면A 프록시 객체는 A메소드와 A advisor라는 부가기능이 추가된 클래스같은 형태로 구현되고, 스프링 빈으로 등록된다고 이해를 하면 되는건가요?? 왜냐하면, 제가 이해한게 맞다면, 아래와 같이 proxy가 advisors를 호출한 뒤에, target을 호출한다는 개념이 잘 이해가 되질 않습니다. proxy가 target의 비지니스 로직도 가지고 있고, advisor도 가지고 있는 객체라서 proxy에서 내부적으로 로직을 다 처리하면 되는 것 아닌가요?? 설명 부탁드립니다 감사합니다
-
미해결스프링 핵심 원리 - 고급편
스프링의 빈 후처리기와 프록시 그리고 타겟에 대해 질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 항상 강의 잘 보고 있습니다. 강의에서 1.생성 : 스프링이 스프링 빈 대상이 되는 객체를 생성함 2.전달 : 생성된 객체를 빈 저장소에 등록하기 직전에 빈 후처리기에 전달함 ~ 그 후에프록시 적용대상인 클래스가 있으면3.프록시 생성 : 프록시 적용 대상이고, 프록시를 생성하고 반환해서 프록시를 스프링 빈으로 등록한다. 라고 말씀하셨습니다. 그 후에, 생성된 프록시와 어드바이저의 동작 과정을 설명하실 때 , client -> ( proxy <-> advisors ) -> target 이런 동작 과정이라고말씀하셨는데 이 부분에서 이해가 안되는 부분이 있습니다. 1.프록시 객체를 생성했는데 target을 호출하는 이유가 무엇인가요?예를 들어,프록시 객체는 target을 기반으로 만들어진 클래스라고 이해를 했습니다.그러면 프록시 객체는 target의 구현체로서 target의 메소드도 가지고 있고, advisor 메소드도 가지고 있는 것 아닌가요?그래서 그냥 타겟을 호출할 필요없이, 프록시 객체에서 모든 요청을 처리하면 되는것 아닌가요?? 왜 프록시 객체는 advisor을 호출하고, 다시 타겟을 통해서 메서드를 또 실행하는건가요? 즉, 전 프록시 객체를 만든다는 것을 아래와 같은 예시로 이해를 했습니다. 그래서 굳이 target을 다시 호출하지 않고, 프록시 객체가 모든 요청을 처리하는게 맞는거 같은데 왜 target을 다시 호출하는건가요?? // AClasspublic class AClass { public void say() { System.out.println("Hello from AClass!"); }}// LoggingAspectㅇ@Aspect@Componentpublic class LoggingAspect { @Before("execution(* com.example.AClass.say(..))") public void logBefore() { System.out.println("Before calling say method"); }} //Proxypublic class AClassProxy extends AClass { @Override public void say() { logBefore(); // 로그 출력 super.say(); // 실제 AClass의 say 메서드 호출 } public void logBefore() { System.out.println("Before calling say method"); }}감사합니다.