묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 핵심 원리 - 고급편
CallServiceV1
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)예[질문 내용]강의와 자바 버전이 다르긴 합니다. 자바 버전이 다른 이슈로 다른 정상 작동 되는 테스트에서도 아래 경고가 발생하긴합니다.WARNING: A Java agent has been loaded dynamically (/Users/yunsang-won/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.14.17/e3c251a39dc90badaf71c83427ba46840f219d8d/byte-buddy-agent-1.14.17.jar)WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warningWARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more informationWARNING: Dynamic loading of agents will be disallowed by default in a future releaseCallserviceV1 생성 후 테스트 코드 실행해보면 아래와 같은 에러가 발생합니다 뭐가 문제일까요 ?ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [MergedContextConfiguration@6fc29daa testClass = hello.aop.internalcall.CallService0Test, locations = [], classes = [hello.aop.AopApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@65a15628, [ImportsContextCustomizer@2f66f0d0 key = [hello.aop.internalcall.CallService0]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7d1cfb8b, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@39655d3e, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@6138e79a, org.springframework.boot.test.context.SpringBootTestAnnotation@373420a5], contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
-
미해결스프링 핵심 원리 - 고급편
AOP 실전예제 질문
@ClassAop @Component public class MemberServiceImpl implements MemberService{ @Override @MethodAop("test value") public String hello(String param) { return "ok"; } public String internal(String param) { return "ok"; } }에서 @ClassAop와 @MethodAop annotation은 왜 만든건가요? 활용이 안된거 같은데요????
-
미해결스프링 핵심 원리 - 고급편
this와 target 차이
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요. 선생님.덕분에 인강을 통해서 스프링에 대해서 깊은 이해와 함께 학습을 하고 있습니다. 매우 감사드립니다.영상 강의를 듣던 중에 this 와 target 의 차이를 공부하던 중에 이해가 되지 않는 부분이 있습니다.MemberServiceImpl 구체 클래스 지정**this(hello.aop.member.MemberServiceImpl) : proxy 객체를 보고 판단한다. JDK 동적 프록시로 만들어진 proxy 객체는 MemberService 인터페이스를 기반으로 구현된 새로운 클래스다. 따라서 MemberServiceImpl 를 전혀 알지 못하므로 AOP 적용 대상이 아니다. target(hello.aop.member.MemberServiceImpl) : target 객체를 보고 판단한다. target 객체가 MemberServiceImpl 타입이므로 AOP 적용 대상이다.이 분에서 이해가 되지 않는 것이 있습니다. 스프링 AOP는 프록시 기반의 AOP를 구현하고 있으며, 스프링 컨테이너의 관리 하에서 프록시 객체를 기반으로 AOP를 적용한다고 이해하고 있습니다. 더불어 프록시 생성 방법은 JDK 동적 프록시(인터페이스 기반 구현 프록시)와 CGLIB(구체 클래스 기반 상속 프록시) 를 통해 알고 있습니다. this 와 target 지시자를 사용하면,this 는 결국 런타임에서 동적으로 생성된 프록시를 대상으로 aop를 적용하는 것이며, 이때 프록시는 JDK 동적 프록시와 CGLIB 중에 생성된 것을 대상으로 한다고 이해하고 있습니다.target 은 실제 대상 객체를 호출하는데, 대상 객체는 프록시 아닌데 어떻게 aop를 적용하는지 이해가 안됩니다.
-
미해결스프링 핵심 원리 - 고급편
빈 후처리기-적용 관련 질문
AppV1Config.class, AppV2Config.class를 BeanPostProcessorConfig 에서 주석처리하고아래와 같이 ProxyApplication 에서 import를 해도 정상 실행됩니다.맞는건가요? @Import({BeanPostProcessorConfig.class,AppV1Config.class, AppV2Config.class}) @SpringBootApplication(scanBasePackages = "hello.proxy.app") public class ProxyApplication { public static void main(String[] args) { SpringApplication.run(ProxyApplication.class, args); }
-
미해결스프링 핵심 원리 - 고급편
Args vs Execution 테스트 설명 중 문의 드립니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]@Test @DisplayName("파라메터 부모 타입으로 매치") void argsMatchDynamic() { // args pointcut.setExpression("args(String)"); Assertions.assertTrue(pointcut.getClassFilter().matches(MemberServiceImpl.class)); pointcut.setExpression("args(Object)"); Assertions.assertTrue(pointcut.getClassFilter().matches(MemberServiceImpl.class)); pointcut.setExpression("args(java.io.Serializable)"); Assertions.assertTrue(pointcut.getClassFilter().matches(MemberServiceImpl.class)); // execution pointcut.setExpression("execution(* *(String))"); Assertions.assertTrue(pointcut.getClassFilter().matches(MemberServiceImpl.class)); pointcut.setExpression("execution(* *(Object))"); Assertions.assertTrue(pointcut.getClassFilter().matches(MemberServiceImpl.class)); pointcut.setExpression("execution(* *(java.io.Serializable))"); Assertions.assertTrue(pointcut.getClassFilter().matches(MemberServiceImpl.class)); } args는 동적 검사라 검색 되어야 맞지만 excution은 정적 타입 검사라서 저게 안된다고 하셨지만 해당 테스트 결과 true로 반환이 됩니다. 혹시나 spring boot 버전 문제일까 싶어서 2.5.5, 3.3.0 두곳에서 테스트 했습니다
-
미해결스프링 핵심 원리 - 고급편
스프링에서 제공하는 애너테이션들은 AOP 가 어떻게 적용되나요?
강의를 보면 커스텀으로 만드는 애너테이션들은 @Aspect 설정으로 등록이 가능한데요,스프링이 제공하는 대표적으로 @Transactional 같은 애너테이션들은 라이브러리를 뒤져봐도 @Aspect 설정을 두는 곳이 없어서 어떻게 프록시를 생성하는지 궁금합니다!
-
미해결스프링 핵심 원리 - 고급편
싱글톤 빈에서의 필드 변수를 사용에도 불구하고 동시성 문제가 일어나지 않습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강의를 보고 코딩을 해서 실행을 해보니깐 싱글톤 빈을 사용함에도 불구하고 로컬 쓰레드 환경처럼 서로 값에 영향이 가지 않는 예제와 다른 결과가 나왔습니다. 혹시나 제가 잘못 코딩을 하여 이런 결과가 나온 것인지 소스 코드를 이용해서 FieldLogTrace를 사용하여 예제를 실행해보았지만, 결과는 똑같이 서로 영향을 미치지 않는 결과가 나왔습니다. 스프링이 최신 버전(테스트 기준 3.3.0)으로 업데이트가 되면서 이와 관련해서 따로 바뀐 부분이 있는지 궁금합니다.
-
미해결스프링 핵심 원리 - 고급편
인터페이스기반 프록시 적용 오류 발생
로그를 보면 처리는 다 되는거 같은데 마지막에 오류 메세지를 출력하네요????https://blog.naver.com/jfk6725수고하세요
-
미해결스프링 핵심 원리 - 고급편
스프링 문의드립니다.
해결함 !
-
미해결스프링 핵심 원리 - 고급편
로그추적기V1 테스트에서 오류납니다.
구글 클라우드를 사용할 수 있는 환경이 안되서 제 블로그 링크를 붙입니다.https://blog.naver.com/jfk6725/223474471383오류 내용입니다.Execution failed for task ':test'.> There were failing tests. See the report at: file:///C:/CodingStudy/%EC%8A%A4%ED%94%84%EB%A7%81/advanced/advanced/build/reports/tests/test/index.html* Try:> Run with --scan to get full insights.BUILD FAILED in 3s4 actionable tasks: 2 executed, 2 up-to-date
-
미해결코딩으로 학습하는 GoF의 디자인 패턴
volatile 사용 이유에 대해서 여쭤보고 싶습니다!
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. synchronized 메서드 블록에서 사용되는 모든 공유변수는 동시성처리를 위해서 공유 변수에 volatile 키워드가 없어도 가시성이 확보되는 것으로 배웠는데 혹시 제가 잘못 알고있는건지 궁금해서 질문드립니다!
-
미해결스프링 핵심 원리 - 고급편
선생님 작성한 정적 팩토리 메서드에 대해 의견 주실 수 있으실까요??
안녕하세요! 프로젝트와 관련해 코드를 작성하다 궁금한 점이 생겨 질문 드립니다..! 혹 선생님께서는 정적 팩토리 메소드의 역할이 어디까지라고 생각하실까요? 저는 팩토리 메소드이기 때문에 1. 단순히 파라미터를 받아 생성자를 통해 인스턴스를 생성하는 것 뿐만 아니라, 인스턴스를 생성하기 위해 2. 파라미터 valiation을 확인하고, 인스턴스 생성을 위한 데이터들을 가공하는 과정 또한 포함해도 괜찮은 것이 아닌가 하였는데,저와 다른 의견 중에서는 팩토리 메소드는 가공이 전부 완료된 값을 단순히 받아서 인스턴스를 new 하기만 해야 한다는 의견이 있더라구요. 가공은 서비스 클래스에서 수행하구요! 예를 들면 아래와 같은 메소드가 validation과 데이터 가공을 처리하는 팩토리 메소드의 예시입니다 ::public static SearchRequest from( AnotherRequest request) { 55 //AnotherRequest 클래스로부터 SearchRequest 클래스를 생성함. if(request.get고객리스트().size() > 9) { 56 //validation? 혹은 비즈니스 로직? throw new Exception(); 57 } 58 //아래부터 데이터 가공 List<Passenger> 새로운 고객리스트 = request.get고객리스트().stream() 59 .map(p -> new Passenger(p.get생일(), p.get성별()) ) 60 .collect(Collectors.toList()); 61 62 //인스턴스 생성 후 return return new SearchRequest(새로운 고객리스트); 63 } 또한 webClient를 이용해 외부로 API 요청을 보내고자 할 때, path 값을 관리하는 과정에서,해당 path 값 ( ex. /a/b/xxx ) 을 반드시 webClient를 변수로 주입받아 실제 통신을 하는 class에서 가지고 있는 것과 혹은 통신 시 사용되는 request 데이터 dto 에서 그 변수 값을 가지고, 실제 통신을 하는 class에서는 request dto에서 getPath()를 통해 가져와 사용하는 것 어느 부분이 더 적절하다고 생각하실까요?저는 2번의 경우 webClient를 사용하는 클래스에서 추가적으로 여러 개의 path에 대한 상수 변수를 가지고 있을 필요가 없고 getPath()라는 메소드를 통해서 request dto의 종류를 신경쓰지 않고 일관되게 가져올 수 있다는 점에서 2번이 더 괜찮다고 생각을 하였는데, 다른 의견에서는 패스 값은 통신에 사용되는 값이기 때문에 dto가 아닌 통신을 하는 클래스가 가져야 하는게 더 자연스럽다. 그래서 새 기능이 추가되었을 때 통신을 하는 클래스 ( webClient를 변수로 가진 ) 에 패스에 대한 상수변수를 추가하고 패스에 따른 통신 메서드를 추가하는 것이 더 낫다. 라는 의견이 있었습니다. 코드 스타일에 따라 정답은 없겠지만, OOP의 입장에서 선생님의 의견을 여쭙고자 합니다! 답변 해주시면 정말 감사하겠습니다!
-
미해결스프링 핵심 원리 - 고급편
LogTraceAspect nolog
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] package hello.proxy.config.v6_aop.aspect; import hello.proxy.trace.TraceStatus; import hello.proxy.trace.logtrace.LogTrace; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import java.lang.reflect.Method; @Slf4j @Aspect public class LogTraceAspect { private final LogTrace logTrace; public LogTraceAspect(LogTrace logTrace) { this.logTrace = logTrace; } @Around("execution(* hello.proxy.app..*(..))") public Object execute(ProceedingJoinPoint joinPoint) throws Throwable { TraceStatus status = null; try { String message = joinPoint.getSignature().toShortString(); status = logTrace.begin(message); //로직 호출 Object result = joinPoint.proceed(); logTrace.end(status); return result; } catch (Exception e) { logTrace.exception(status, e); throw e; } } }nolog 요청에는 로그를 안남기기 위해서 포인트컷을 수정해야되는거 아닌가요???
-
미해결스프링 핵심 원리 - 고급편
proxy프로젝트가 임포트되질않습니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]proxy-start 프로젝트를 다운받고 폴더이름 proxy로 변경후강의에서 말씀하신 데로 open as project로 프로젝트를 실행했는데 "Connection refused: no further information"에러가 뜨면서 프로젝트가 임포트되질않습니다. 사진에서 처럼 프로젝트쪽에 아예 모듈이 임포트가 안됩니다. 강의에서 제공하는 압축파일에서 전혀 손대지 않고 그대로 사용하엿습니다.자주 하는 질문에 스프링3버전이상 jdk17버전 이상 사용은해당문제와는 관련이 없어보이긴 했지만 (advanced프로젝트는 문제 없이 작동하였음)스프링버전3이상 자바17로 세팅해도 여전히 같은현상이 반복됩니다 확인부탁드립니다.
-
미해결스프링 핵심 원리 - 고급편
템플릿 메소드 패턴과 전략 패턴
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강의에서 템플릿 메소드의 경우에는 부모 클래스가 바뀌면 자식 클래스에 영향을 미치는 반면에, 전략 패턴의 경우엔 Context 코드가 변경되더라고 Strategy부분에 영향을 미치지 않는다고 설명하셨는데,,, 이 부분이 정학히 이해가 되지않습니다. 혹시 간단한 예시를 통해 이 둘의 차이를 알 수 있을까요ㅠ?
-
미해결스프링 핵심 원리 - 고급편
interfaceProxy에 대해서 질문 있어요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]인터페이스 프록시들이 잘 살펴보면 조금씩은 차이가 있지만 비슷한데 이것들을 전략패턴이나 아니면 다른 방식으로 또 통합 가능한가요?
-
해결됨C개발자를 위한 최소한의 C++
네가지 형변환 강의 질문
제가 c++ 강의를 보면서 무언가 빼먹은거 같아서 질문을 드려봅니다...강의 설명 중 3분즈음에 등장하는 const_cast를 설명하실 때 궁금한 내용입니다.const MyData& rdata = a; 일때rdata의 멤버접근을 할 수 있는거는 const 키워드가 붙은것만 가능하다고 하셨는데그 자세한 이유가 궁금합니다 <상수형 참조가 상수형 메서드만 호출>
-
해결됨C개발자를 위한 최소한의 C++
CMyString Step10 강의 질문
강의 2분 50초 쯤에 등장하는virtual void onSetData(const char*& pParam)에서 포인터 변수의 값을 바꾸기 위해 &참조자를 추가하셨습니다.const가 붙은 시점에서 연산자 우선순위가 어떻길래 값이 변경가능해진 것인지 궁금합니다!
-
미해결스프링 핵심 원리 - 고급편
인터페이스 객체지향에 대해..
김영한님 강의를 듣다보면 객체지향다형성, 인터페이스프로시 이런얘기를 많이들었습니다만ㅠㅠ이해가 안되는거 하나 여쭙고싶네요..보통 스프링 프로젝트 보면컨트롤러에 서비스 인터페이스 선언해두고이를 다시 서비스임플로 구현하자나요이걸 도대체 왜 하는걸까요?ㅠㅠ제 생각엔 인터페이스 둔다는것 자체가구현체를 필요에 따라 갈아끼우겠다는건데..보통 컨트롤러에 선언해둔 서비스 인터페이스의 의도를 알고싶습니다.,../ㅠㅠㅠ
-
미해결스프링 핵심 원리 - 고급편
포인트컷 지시자와 매개변수 전달
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 네3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 네[질문 내용]매개변수 관련된 부분 학습 중에 헷갈리는 내용이 있어서 질문 드립니다.예를 들어 @annotation은 특정 어노테이션 기반으로 aop 프록시 대상을 정하는 것으로 배웠고, 다음과 같이 사용했습니다. @Around("@annotation(hello.aop.member.annotation.MethodAop)") public Object doAtAnnotation(ProceedingJoinPoint joinPoint) throws Throwable { log.info("[@annotation] {}", joinPoint.getSignature()); return joinPoint.proceed(); }그런데 매개변수 전달에서 @annotation은 특정 annotation을 전달하는 것으로도 보이는데요, @Before("allMember() && @annotation(annotation)") public void atAnnotation(JoinPoint joinPoint, MethodAop annotation) { log.info("[@annotation]{}, annotationValue={}", joinPoint.getSignature(), annotation.value()); }그렇다면 두 번째 경우에, aop 프록시 대상에 @MethodAop를 갖고 있는 대상에 대해서 적용이 되는 걸까요? 해당 어노테이션만 전달하는 건지, 해당 어노테이션을 갖고 있는 경우에 적용하는 기능까지 포함된 건지 (이 경우엔 생략된걸까요?) 궁금합니다