묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨C개발자를 위한 최소한의 C++
스크립트 오류
7:38초 경 텍스트가 그러면 그거랑 5랑 더해서 연산의 임시결과가 떨어졌겠죠 그게 15가 저장되어 있는 integer 인스턴스일텐데, 사라져야 될 운명이었으나 거기에다 이름을 부여한거죠. 인데 수정 제안할랬더니 길어서 짤리네요. 관리자분께서 스크립트 시간 자른 후 나눠서 바꿔주셔야 할 것 같아요.지난 시간 것도 유사한 게 있었어요. 통으로 날아가 있어서... 조치 부탁드립니다! 노트 필기하는 마음으로 스크립트 수정 중입니다. ㅎㅎ
-
미해결스프링 핵심 원리 - 고급편
다중 상속
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]인스턴트에 인터페이스가 있다면 JDK 동적 프록시를 사용하고 그렇기 때문에 "proxyFactory.getProxy()"의 반환값을 인터페이스로 타입 캐스팅할 수 있다고 알려주셨습니다. 그런데 만약이 객체가 인터페이스를 다중 상속하고 있다면 어떻게 동작하나요? 예를 들어서이런 예제가 있다고하면 InterfaceImpl는 A와 B 인터페이스를 모두 구현한 건데 JDK 동적 프록시는 InterfaceImpl이 A를 구현한건지 B를 구현한건지 어떻게 구분할까요?참고로 test 코드를 작성해보니 A와 B 둘다 타입 캐스팅이 되네요
-
미해결스프링 핵심 원리 - 고급편
http://localhost:8080/v0/request?itemId=hello 실행 시 에러
1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]예제 프로젝트 만들기에서 http://localhost:8080/v0/request?itemId=hello실행 시에 java.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specified, and parameter name information not found in class file either.이런 에러가 뜹니다.소스는 하도 안되서 다 복붙 해봤는데도 안됩니다.자바 17에 스프링부트 3.2.0 버전입니다.
-
미해결스프링 핵심 원리 - 고급편
프로젝트 생성시 자바 버전 관련
2023-11-25 기준으로 spring initializer 에 자바 11버전이 지원이 안되는건지 그림과 같이 21,17 버전만 있습니다 ㅜㅜ 혹시 왜그런건지...그리고 11버전으로느 ㄴ다운받을 수 없는건지 궁금합니다.
-
미해결코딩으로 학습하는 GoF의 디자인 패턴
싱글톤 패턴을 깨트리는 방법
싱글톤 패턴을 깨트리는 방법으로 Reflection, 직렬화/역직렬화 두 가지 방법을 설명해주셨고 굉장히 흥미롭게 들었습니다.다만 들으면서 싱글톤을 깨트리는 방법이 존재한다고 하더라도 저걸 고려하면서 코드를 짜야할까?라는 생각이 들었습니다.저는 아직 취준생이라 그런지 리플렉션이나, 직렬화/역직렬화 방식으로 객체를 생성해본 적이 없어서 이런 생각을 하는 거 같습니다. 실무에서 리플렉션을 이용해서 객체를 생성하는 경우가 종종 발생하나요? 굳이 왜 리플렉션을 이용해 객체를 생성하는 건지 어떨 때, 리플렉션을 사용해서 객체를 생성하는지 예시가 궁금합니다. 스프링을 쓰면서 직렬화/역직렬화가 이루어지는 것은 아래 정도의 케이스밖에 생각나지 않아요. 1. Client <-> Server 데이터를 주고받을 때, (dto)Server <-> DB 데이터를 주고받을 때, (Entity)하지만 DTO나 Entity를 싱글톤으로 만들어줄 이유가 없으므로 직렬화/역직렬화 때문에 싱글톤이 깨지는 경우가 발생할까가 의문입니다. <질문 정리>리플렉션이나 이용해서 객체를 생성하는 경우가 실무에서 종종 사용되는 방법 인가요?직렬화/역직렬화가 이루어지는 클래스는 싱글톤으로 설정할만한 클래스가 아닐 텐데 직렬화/역직렬화 때문에 싱글톤이 깨지는 경우가 실무에서 종종 발생하는 문제인가요?1~2번 질문에 대한 답이 만약 저렇게 객체를 생성하는 경우는 없다 라면 싱글톤을 구현할 때 저런 것을 고려하며 짤 이유가 있나요?
-
미해결스프링 핵심 원리 - 고급편
어떻게 ProxyFactory() 생성시 인터페이스가 있는 target과 없는 target을 구분하는지 궁금합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]new ProxyFactory()생성시 내부 로직의 생성자에는 setTarget(target);과setInterface(ClassUtils.getAllInterfaces(target)); 으로 이루어져있고 setInterface(...)의 로직에는 Assert.notNull으로 인터페이스가 없을 경우 exception을 발생하게 되어있던데 어떻게 인터페이스가 없는 target으로 ProxyFactory가 생성되는지 궁금합니다.
-
미해결스프링 핵심 원리 - 고급편
Parent는 굳이 빈을 등록할 필요가 없는 이유가 궁금합니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]본 강의 6:20초 쯤, "Parent는 굳이 @Bean으로 등록할 필요가 없겠네요." 라고 말씀해주셨는데, 이 부분이 잘 이해가 안 되어 문의드립니다!저희가 지금까지 배웠던 AOP는 스프링의 어플리케이션 컨텍스트에 객체를 @Bean으로 등록할 때, 실제 객체 대신에 프록시 객체를 등록하는 방식으로 동작했었는데,만약 Parent 객체를 @Bean으로 등록하지 않는다면 @target 을 통한 parentMethod 호출 시에도 Advice의 부가기능이 실행되지 않는 것 아닌가요~? 제가 잘못 이해하고 있는 부분이 있다면 짚어주시기를 부탁드립니다!
-
미해결스프링 핵심 원리 - 고급편
LogTrace의 Bean을 메인 클래스에서 생성한 이유
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? [질문 내용]LogTrace의 @Bean 어노테이션으로 빈 생성할 때 메인 클래스에서 생성한 이유가 따로 있으신가요??Config 클래스에서 하지 않고 따로 메인 클래스에서 하신 이유가 있으신가 해서요@Bean 어노테이션은 다른 클래스에서도 사용이 가능한지도 궁금합니다
-
미해결스프링 핵심 원리 - 고급편
@target 관련
안녕하세요 강의 잘 듣고 있습니다.강의 말미에 args, @args, @target은 단독으로 사용하면 안 된다고 하셨고 다음과 같은 이유를 말씀하셨습니다. '실제 객체 인스턴스가 생성되고 런타임에 적용 여부를 알 수 있다'아규먼트의 실제 타입을 요구하는 args, @args는 비교적 직관적으로 이해했는데, @target은 어째서 런타임에 적용 여부를 알아야만 하는 걸까요? 마치 @within이 그런 것처럼 클래스 내부에 특정 어노테이션이 있으면 해당 클래스부터 부모 클래스까지 AOP를 적용하면 될 것 같은데 말이죠.
-
해결됨스프링 핵심 원리 - 고급편
포인트컷 표현식 질문
안녕하세요 강의 잘 듣고있습니다.강의에서 등장하는 AtTargetAtWithinAspect의 execution 표현식을 보면 * hello.aop..*(..)로 기재되어 있습니다.이전 강의에서 학습했던 표현식(* hello.aop..*.*(..))과 어떤 차이점이 있는건가요?
-
해결됨스프링 핵심 원리 - 고급편
@AfterReturning에서 질문있습니다.
안녕하세요 강사님!강사님께서 말씀해주신 AOP로 구현하면 좋은 기능을 실제 코드로 작성해봤습니다.로그 트레이스기능에 매서드 종료가 1초 5초 10초가 될때 로그 레벨을 높여서 로그를 찍는 기능입니다. @Aspect @Slf4j static class LogTraceSelf { ThreadLocal<TraceStatus> trace = new ThreadLocal<>(); private TraceStatus SynchronizedTrace(){ TraceStatus traceStatus = trace.get(); if (traceStatus == null) { trace.set(new TraceStatus()); traceStatus = trace.get(); } return traceStatus; } @Pointcut("@annotation(hello.aop.exam.annotation.Trace)") public void logTrace() {} @Before("logTrace()") public void doTrace(JoinPoint joinPoint) { TraceStatus traceStatus = SynchronizedTrace(); traceStatus.begin(joinPoint.getSignature().getName()); } @AfterReturning("logTrace()") public void doTraceSuccess(JoinPoint joinPoint) { TraceStatus traceStatus = SynchronizedTrace(); long gap = traceStatus.end(joinPoint.getSignature().getName()); } @AfterThrowing(value = "logTrace()", throwing = "ex") public void doTraceException(JoinPoint joinPoint, Exception ex) { TraceStatus traceStatus = SynchronizedTrace(); traceStatus.end(joinPoint.getSignature().getName(),ex); } }조인포인트 실행 권한이 필요없는 부가 기능이다보니@Around 사용을 하지 않고 나누어서 처리를 하다보니 불필요한 코드가 더 증가하게되었습니다.그리고 @Around와 다르게 어드바이스내 지역변수에 TraceStatus를 저장하고 사용할수 없기때문에ThreadLoacal에 공유할 데이터와 본인이 가지고 있어야하는 timestamp도 저장했습니다.@Slf4j public class TraceStatus { private final String id; private int depth = 0; private Deque<Long> timeStampHolder = new ArrayDeque<>(); private final int offsetInfoMs; private final int offsetWarningMs; private final int offsetErrorMs; }기능은 stack 자료구조를 활용해서 begin을 할때마다 timeStampHolder에 시작시간을 저장합니다.end를 호출하면 pop으로 자신이 넣은 시작 시간을 꺼내서 시간을 계산하고 로그를 출력합니다.기타 기능 메서드들은 강사님이 작성하신거와 유사해서 제외했습니다. 이제 소요된 시간이 1초, 5초, 10초가 걸릴 경우 info,warning,error로 출력하는 로그를 남기려고할때어드바이스가 조건을 가지고 추가 기능을 만든다.위 코드처럼 로그 트레이스 내에 저장하고 로그 트레이스 내부에서 출력하도록 한다.경고 알림용 트레이스를 따로 만들고 상태를 전달한다.제 생각은 트레이스에게 넘길경우 트레이스를 인터페이스로 만들어서 필요에 따라 다른 트레이스를 사용한다고 한다면 이 기능을 계속 구현해야 된다는 단점이 생길거 같습니다.저라면 어드바이스에서 소요시간을 트레이스에게 받아서 추가 로직을 수행하려고 할거같습니다. 강사님께서 코드를 작성하신다면어떤 포인트컷을 사용하셔서 구현하실건지,그리고 애노테이션에서 넘어온 값을 가지고 어드바이스에서 처리하게 하시는지아니면 로그 트레이스 내에서 처리하게 하실건지 그 이유가 궁금합니다.
-
해결됨스프링 핵심 원리 - 고급편
Enhancer.setSuperclass
/** * Set the class which the generated class will extend. As a convenience, * if the supplied superclass is actually an interface, <code>setInterfaces</code> * will be called with the appropriate argument instead. * A non-interface argument must not be declared as final, and must have an * accessible constructor. * @param superclass class to extend or interface to implement * @see #setInterfaces(Class[]) */ public void setSuperclass(Class superclass) { if (superclass != null && superclass.isInterface()) { setInterfaces(new Class[]{superclass}); // SPRING PATCH BEGIN setContextClass(superclass); // SPRING PATCH END } else if (superclass != null && superclass.equals(Object.class)) { // affects choice of ClassLoader this.superclass = null; } else { this.superclass = superclass; // SPRING PATCH BEGIN setContextClass(superclass); // SPRING PATCH END } } 강사님 PDF 5.동적 프록시 기술 마지막 장인터페이스가 있는 경우에는 JDK 동적 프록시를 적용하고, 그렇지 않은 경우에는 CGLIB를 적용하려면어떻게 해야할까?두 기술을 함께 사용할 때 부가 기능을 제공하기 위해서 JDK 동적 프록시가 제공하는InvocationHandler 와 CGLIB가 제공하는 MethodInterceptor 를 각각 중복으로 만들어서 관리해야할까?라고 작성되어 있더라구요진짜 구현 클래스만 프록시를 만들어 주는지 궁금해서 찾아보니Enhancer 클래스 내부 메서드를 보면 setSuperclass 가 있는데내부에 인터페이스가 들어오던, 구체 클래스가 들어오던 알아서 구현체를 만들어준다고 되어있더라구요Enhancer 클래스 주석에도하지만 프록시가 인터페이스를 구현하는 것 외에 구체적인 기본 클래스를 확장할 수 있게 해준 것입니다.라고 작성되어 있습니다. 실제 코드로 작성해도 잘 동작합니다.package hello.proxy.my; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; @Slf4j public class EnhancerTest { @Test void enhancerInterface() { MyInterfaceImpl myInterface = new MyInterfaceImpl(); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MyInterface.class); enhancer.setCallback(new MyInterceptor(myInterface)); MyInterface myInterfaceProxy = (MyInterface) enhancer.create(); myInterfaceProxy.call(); } static class MyInterceptor implements MethodInterceptor { private final MyInterface myInterface; public MyInterceptor(MyInterface myInterface) { this.myInterface = myInterface; } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { log.info("로그 시작"); myInterface.call(); log.info("로그 종료"); return null; } } } interface MyInterface { void call(); } @Slf4j class MyInterfaceImpl implements MyInterface { @Override public void call() { log.info("나는 인터페이스를 구현한 클래스입니다."); } } //log 19:11:27.315 [Test worker] INFO hello.proxy.my.EnhancerTest - 로그 시작 19:11:27.317 [Test worker] INFO hello.proxy.my.MyInterfaceImpl - 나는 인터페이스를 구현한 클래스입니다. 19:11:27.317 [Test worker] INFO hello.proxy.my.EnhancerTest - 로그 종료Enhancer 클래스도 인터페이스나 구체 클래스를 모두 프록시로 생성할 수 있고더 향상된 호출 핸들러을 제공하는 MethodInterceptor 를 사용할 수도 있습니다.제 생각에는 MethodInterceptor 사용할 수 있는 Enhancer 프록시 객체를 디폴트로 사용할거같거든요 그런데 ProxyFactory는 false로 인터페이스랑 구체 클래스를 분리해서 생성하게 했더라구요 그 이유도 궁금합니다.제가 이해한게 맞다면 Enhancer도 인터페이스를 구현할 수 있는데 별도로 개발해야한다고 말씀하신 이유도 궁금합니다 !!
-
미해결스프링 핵심 원리 - 고급편
어드바이저 빈에 대해서는 프록시를 적용하지 않나요?
자동 프록시 생성기는 빈이 후처리기로 들어오면 어드바이저 빈과 후처리기로 들어온 빈을 매칭해서 프록시의 생성여부를 결정하는 걸로 이해했습니다.그러면 처음에 어드바이저 빈을 생성할 때에는 자동 프록시 생성기가 '얘는 어드바이저 빈이구나. 프록시를 생성할 필요가 없겠어' 라고 판단하고 걸러주는 건가요?
-
미해결스프링 핵심 원리 - 고급편
실행순서
안녕하세요실행 순서: @Around , @Before , @After , @AfterReturning , @AfterThrowing 라고 적어주셨는데 @After 이게 왜3 번째로 실행된다고 표현 해주신게 이해가 조금 안갑니다. 실제로는 @AfterReturnin 다음에 실행되는거 아닌가요 ?
-
미해결스프링 핵심 원리 - 고급편
setProxyTargetClass()
문서에는 true가 기본적으로 설정해서 사용한다고 적혀있는데 default는 false 아닌가요?? 그냥 true를 기본적으로 많이 쓴다는 소리일까요 ?
-
미해결코딩으로 학습하는 GoF의 디자인 패턴
코드에 약간 오타가 있는거 같습니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.안녕하세요. 백기선님수업을 잘 듣고 있습니다. 제 생각에 간단한(?) 오타같은게 있는거 같아서 제보드립니다. 혹시 오타가 아니라면 제가 잘못 이해한 부분을 말씀 부탁드리겠습니다.옵저버 패턴 3부 - 1:56초쯤 unregister 를 subject가 "디자인패턴"인 것에 대해서 user2 를 해지 해주었는데요.이미 user 2는 오징어게임에만 등록중입니다. 그래서 결과값도 user2 가 보낸 "옵저버 패턴 장, 단점 보는 중" 이 user1한테 가서 출력된거 같습니다.아마 user1을 해지하거나 user2를 오징어게임에 대해서 해지하려고 하지 않았나 싶습니다..
-
미해결스프링 핵심 원리 - 고급편
joinPoint.proceed() 실행결과인 result 에 관한 질문
안녕하세요강의 정말 감사히 잘 듣고 있습니다.다름이 아니라 예전부터 궁금했던 건데 Object result = joinPoint.proceed();여기서 각 비즈니스 로직(target) 을 실행시키고 난 뒤에 항상 result 를 받습니다.그러나 정작 result 를 활용하여 어떤 동작을 하는 것은 보지를 못해서요....이 result 를 항상 return 시켜주는 데 1) 어떠한 상황에서 result 값을 유용하게 사용할 수 있는지?2) result 를 return 하는데 어디로 return 하는지?가 궁금합니다.혹시 제가 놓친 부분이 있는지 지적해주시면 감사하겠습니다.(항상 감사합니다. 소중한 강의 정말 잘 보고 있습니다)
-
미해결스프링 핵심 원리 - 고급편
프록시 기능
프록시 주요 기능중접근제어 캐싱 지연로딩이건프록시 없이는 불가능한 기술인가요??프록시 기술이 꼭 필요한 기술인지 궁금해서요 !
-
미해결스프링 핵심 원리 - 고급편
스프링에서 CGLiB를 기본적으로 설정했는데, JDK 프록시 방식이 더 유용한 경우가 있을까요?
스프링에서 CGLiB를 기본적으로 설정했는데, CGLiB와 비교하여 JDK 프록시 방식이 더 유용한 경우가 있을까요?
-
미해결스프링 핵심 원리 - 고급편
4:56쯤에 나오는 포인트 컷 지시자 관련해서 궁금한 점이 있습니다.
강의 4:56쯤 보면, 다음처럼 포인트 컷 지시자를 표현해주는데,execution(* hello.app..*(..)) && @target(hello.aop.member.annotation.ClassAop)앞에 hello.app..*(..))안붙여줘도 뒤 조건에 만족하는 것만 AOP만 적용되지 않나요?앞에 위와 같은 조건을 붙여주신 이유가 궁금합니다.