Home

0

Spring 핵심원리 고급편 - 리플렉션

목차 Spring 핵심원리 고급편 - CGLIB Spring 핵심원리 고급편 - Dynamic Proxy 2 Spring 핵심원리 고급편 - Dynamic Proxy 1 Spring 핵심원리 고급편 - 리플렉션 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 적용 2 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 Spring 핵심원리 고급편 - 인터페이스 프록시 1 Spring 핵심원리 고급편 - Decorator Pattern 2 Spring 핵심원리 고급편 - Decorator Pattern 1 Spring 핵심원리 고급편 - Proxy 패턴 컴포넌트 스캔으로 자동 빈 등록 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스 없는 없는 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스와 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 Spring 핵심원리 고급편 - Strategy 패턴 Spring 핵심원리 고급편 - Template Method 패턴 리플렉션 구체적인 클래스 타입을 알지 못해도 해당 클래스의 메소드, 타입, 변수들을 사용할 수 있도록 하는 자바 API 자바 Reflection 은 실행 중인 자바 프로그램 에서 클래스 정보에 접근하도록 하는 기술입니다. Reflection을 사용하면 클래스나 인터페이스의 이름, 필드의 이름, 타입 및 값, 메서드의 이름, 파라미터 타입 등의 정보를 가져오고 조작할 수 있습니다. 이를 통해 객체의 생성, 필드값 설정, 메서드 호출 등을 동적으로 수행할 수 있습니다. 리플렉션 - API클래스 정보 가져오기 - forNameClass 클래스의 forName 메서드를 사용하여 클래스 정보를 가져옵니다. 예를 들어, 다음과 같이 클래스 정보를 가져올 수 있습니다. Class<?> myClass = Class.forName("com.example.MyClass");

0

컴파일 언어, 인터프리터 언어, 하이브리드 언어

컴파일 언어, 인터프리터 언어, 하이브리드 언어 객체 지향 3요소 객체 지향 설계 5원칙 SOLID 컴파일 언어, 인터프리터 언어, 하이브리드 언어컴파일 언어 고급 언어로 작성된 코드를 Compiler(컴파일러) 를 이용해 목적 코드 로 번역하는 과정을 거치는 언어좁은 의미에서는 소스 코드를 기계어 로 번역해주는 과정을 컴파일이라 한다. 프로그램을 한번에 번연한 후 실행한다. 한번에 모든 소스를 번역하기 때문에 메모리 사용량이 크다. 번역 속도가 느림 실행 속도는 빠름 번역과 실행이 따로 이뤄지기 때문에 실행 파일 (ex. .exe) 이 생성된다. C, C++ 언어가 대표적인 컴파일 언어다. 인터프리터 언어 컴파일 언어와는 다르게 소스코드를 원시코드(기계어)로 번역하는 과정을 거치지 않는 언어Interpreter(인터프리터) 를 이용해 한줄씩 읽어가면서 명령을 처리한다. 번역 속도가 빠름 실행 속도는 느림 번역과 실행이 한번에 이뤄지기 때문에 별도의 실행파일이 만들어지지 않는다. Python, Javascript 가 대표적인 인터프리터 언어다. 하이브리드 언어 컴파일 기법과 인터프리터 기법을 모두 사용하는 언어

0

JPA 연관 관계 - 영속성 전이 Cascade

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 JPA 영속성 전이 Cascade Cascading 이란, 특정 Entity 에 작업을 수행했을 때, 같은 작업이 연관된 Entity 에도 일어나는 것을 의미한다. 영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없다. 엔티티를 연속화 할때 연관된 엔티티도 함께 영속화 하는 편리함을 제공한다. 영속성 전이 옵션 CascadeType.ALL 상위 Entity 에서 발생한 모든 작업을 하위 Entity 로 모두 전파 CascadeType.PERSIST 상위 Entity 를 영속화 하는 작업이 일어 날때 하위 Entity 도 같이 영속화 한다. CascadeType.MERGE 상위 Entity 에서 발생한 Merge 작업을 하위 Entity 까지 Merge 작업을 전파한다. CascadeType.REMOVE 상위 Entity 를 삭제할 때 하위 Entity 까지 삭제한다. CascadeType.REFRESH DataBase 로부터 상위 Entity 를 다시 읽어올때 하위 Entity 까지 다시 읽어온다. CascadeType.DETACH 상위 Entity 를 영속성 컨텍스트에서 제거할 때 하위 Entity 까지 같이 제거한다. @Entity@NoArgsConstructor@AllArgsConstructor@Setter@Getterpublic class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "person", cascade = CascadeType.ALL) private List<Phone> phones = new ArrayList<>(); public void addPhone(Phone phone){ phones.add(phone); phone.setPerson(this); }} @Entity@Builder@NoArgsConstructor@AllArgsConstructor@Getter@Setterpublic class Phone { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long id; public String phoneNumber; @ManyToOne @JoinColumn(name = "PERSON_ID") public Person person;}

0

Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 적용 2

목차 Spring 핵심원리 고급편 - CGLIB Spring 핵심원리 고급편 - Dynamic Proxy 2 Spring 핵심원리 고급편 - Dynamic Proxy 1 Spring 핵심원리 고급편 - 리플렉션 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 적용 2 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 Spring 핵심원리 고급편 - 인터페이스 프록시 1 Spring 핵심원리 고급편 - Decorator Pattern 2 Spring 핵심원리 고급편 - Decorator Pattern 1 Spring 핵심원리 고급편 - Proxy 패턴 컴포넌트 스캔으로 자동 빈 등록 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스 없는 없는 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스와 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 Spring 핵심원리 고급편 - Strategy 패턴 Spring 핵심원리 고급편 - Template Method 패턴 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 적용 2public class OrderRepositoryConcreteProxy extends OrderRepositoryV2 { private final OrderRepositoryV2 target; private final LogTrace logTrace; public OrderRepositoryConcreteProxy(OrderRepositoryV2 target, LogTrace logTrace) { this.target = target; this.logTrace = logTrace; } @Override public void save(String itemId) { TraceStatus status = null; try{ status = logTrace.begin("OrderRepository.request()"); // target 호출 target.save(itemId); logTrace.end(status); }catch (Exception ex){ logTrace.exception(status, ex); throw ex; } }} public class OrderServiceConcreteProxy extends OrderServiceV2 { private final OrderServiceV2 target; private final LogTrace logTrace; public OrderServiceConcreteProxy(OrderServiceV2 target, LogTrace logTrace) { super(null); this.target = target; this.logTrace = logTrace; } @Override public void orderItem(String itemId) { TraceStatus status = null; try{ status = logTrace.begin("OrderService.orderItem()"); // target 호출 target.orderItem(itemId); logTrace.end(status); }catch (Exception ex){ logTrace.exception(status, ex); throw ex; } }} public class OrderControllerConcreteProxy extends OrderControllerV2 { private final OrderControllerV2 target; private final LogTrace logTrace; public OrderControllerConcreteProxy(OrderControllerV2 target, LogTrace logTrace) { super(null); this.target = target; this.logTrace = logTrace; } @Override public String request(String itemId) { TraceStatus status = null; try{ status = logTrace.begin("OrderController.request()"); // target 호출 String result = target.request(itemId); logTrace.end(status); return result; }catch (Exception ex){ logTrace.exception(status, ex); throw ex; } } @Override public String noLog() { return target.noLog(); }} @Configurationpublic class ConcreteProxyConfig { @Bean public OrderControllerV2 orderControllerV2(LogTrace logTrace){ OrderControllerV2 controllerImpl = new OrderControllerV2(orderServiceV2(logTrace)); return new OrderControllerConcreteProxy(controllerImpl, logTrace); } @Bean public OrderServiceV2 orderServiceV2(LogTrace logTrace){ OrderServiceV2 serviceImpl = new OrderServiceV2(orderRepositoryV2(logTrace)); return new OrderServiceConcreteProxy(serviceImpl, logTrace); } @Bean public OrderRepositoryV2 orderRepositoryV2(LogTrace logTrace){ OrderRepositoryV2 repositoryImpl = new OrderRepositoryV2(); return new OrderRepositoryConcreteProxy(repositoryImpl, logTrace); }} //@Import(AppV1Config.class)//@Import({AppV1Config.class, AppV2Config.class})//@Import(InterfaceProxyConfig.class)@Import(ConcreteProxyConfig.class)@SpringBootApplication(scanBasePackages = "hello.proxy.app") //주의public class ProxyApplication { public static void main(String[] args) { SpringApplication.run(ProxyApplication.class, args); } @Bean public LogTrace logTrace(){ return new ThreadLocalLogTrace(); }} 2021-11-28 14:45:36.692 INFO 98295 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [56d57615] OrderController.request()2021-11-28 14:45:36.693 INFO 98295 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [56d57615] |-->OrderService.orderItem()2021-11-28 14:45:36.693 INFO 98295 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [56d57615] | |-->OrderRepository.request()2021-11-28 14:45:37.696 INFO 98295 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [56d57615] | |<--OrderRepository.request() time=1003ms2021-11-28 14:45:37.696 INFO 98295 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [56d57615] |<--OrderService.orderItem() time=1003ms2021-11-28 14:45:37.697 INFO 98295 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [56d57615] OrderController.request() time=1005ms

0

Spring 핵심원리 고급편 - 구체 클래스 기반 프록시

목차 Spring 핵심원리 고급편 - CGLIB Spring 핵심원리 고급편 - Dynamic Proxy 2 Spring 핵심원리 고급편 - Dynamic Proxy 1 Spring 핵심원리 고급편 - 리플렉션 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 적용 2 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 Spring 핵심원리 고급편 - 인터페이스 프록시 1 Spring 핵심원리 고급편 - Decorator Pattern 2 Spring 핵심원리 고급편 - Decorator Pattern 1 Spring 핵심원리 고급편 - Proxy 패턴 컴포넌트 스캔으로 자동 빈 등록 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스 없는 없는 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스와 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 Spring 핵심원리 고급편 - Strategy 패턴 Spring 핵심원리 고급편 - Template Method 패턴 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시@Slf4jpublic class ConcreteLogic { public String operation(){ log.info("ConcreteLogic 실행"); return "data"; }} public class ConcreteClient { private ConcreteLogic concreteLogic; public ConcreteClient(ConcreteLogic concreteLogic) { this.concreteLogic = concreteLogic; } public void execute(){ concreteLogic.operation(); }} @Testvoid noProxy(){ ConcreteLogic concreteLogic = new ConcreteLogic(); ConcreteClient client = new ConcreteClient(concreteLogic); client.execute();} 구체 클래스 기반 프록시 적용 자바에서 다형성은 인터페이스를 구현하든 상위 클래스를 상속하던 상위 타입만 맞으면 다형성이 적용 된다.

0

Spring 핵심원리 고급편 - 인터페이스 프록시 1

목차 Spring 핵심원리 고급편 - CGLIB Spring 핵심원리 고급편 - Dynamic Proxy 2 Spring 핵심원리 고급편 - Dynamic Proxy 1 Spring 핵심원리 고급편 - 리플렉션 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 적용 2 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 Spring 핵심원리 고급편 - 인터페이스 프록시 1 Spring 핵심원리 고급편 - Decorator Pattern 2 Spring 핵심원리 고급편 - Decorator Pattern 1 Spring 핵심원리 고급편 - Proxy 패턴 컴포넌트 스캔으로 자동 빈 등록 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스 없는 없는 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스와 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 Spring 핵심원리 고급편 - Strategy 패턴 Spring 핵심원리 고급편 - Template Method 패턴 @RequiredArgsConstructorpublic class OrderRepositoryInterfaceProxy implements OrderRepositoryV1 { // 실제 객체 참조 private final OrderRepositoryV1 target; private final LogTrace logTrace; @Override public void save(String itemId) { TraceStatus status = null; try{ status = logTrace.begin("OrderRepository.request()"); // target 호출 target.save(itemId); logTrace.end(status); }catch (Exception ex){ logTrace.exception(status, ex); throw ex; } }} @RequiredArgsConstructorpublic class OrderServiceInterfaceProxy implements OrderServiceV1 { private final OrderServiceV1 target; private final LogTrace logTrace; @Override public void orderItem(String itemId) { TraceStatus status = null; try{ status = logTrace.begin("OrderService.orderItem()"); // target 호출 target.orderItem(itemId); logTrace.end(status); }catch (Exception ex){ logTrace.exception(status, ex); throw ex; } }} @RequiredArgsConstructorpublic class OrderControllerInterfaceProxy implements OrderControllerV1 { private final OrderControllerV1 target; private final LogTrace logTrace; @Override public String request(String itemId) { TraceStatus status = null; try{ status = logTrace.begin("OrderController.request()"); // target 호출 String result = target.request(itemId); logTrace.end(status); return result; }catch (Exception ex){ logTrace.exception(status, ex); throw ex; } } @Override public String noLog() { return target.noLog(); }} Proxy Bean 등록@Configurationpublic class InterfaceProxyConfig { @Bean public OrderControllerV1 orderController(LogTrace logTrace){ OrderControllerV1Impl controllerImpl = new OrderControllerV1Impl(orderService(logTrace)); return new OrderControllerInterfaceProxy(controllerImpl, logTrace); } @Bean public OrderServiceV1 orderService(LogTrace logTrace){ OrderServiceV1Impl orderServiceImpl = new OrderServiceV1Impl(orderRepository(logTrace)); return new OrderServiceInterfaceProxy(orderServiceImpl, logTrace); } @Bean public OrderRepositoryV1 orderRepository(LogTrace logTrace){ OrderRepositoryV1 orderRepositoryImpl = new OrderRepositoryV1Impl(); return new OrderRepositoryInterfaceProxy(orderRepositoryImpl, logTrace); }} //@Import(AppV1Config.class)//@Import({AppV1Config.class, AppV2Config.class})@Import(InterfaceProxyConfig.class)@SpringBootApplication(scanBasePackages = "hello.proxy.app") //주의public class ProxyApplication { public static void main(String[] args) { SpringApplication.run(ProxyApplication.class, args); } @Bean public LogTrace logTrace(){ return new ThreadLocalLogTrace(); }} 2021-11-28 13:54:09.793 INFO 97198 --- [nio-8080-exec-2] h.p.trace.logtrace.ThreadLocalLogTrace : [86b4baba] OrderController.request()2021-11-28 13:54:09.795 INFO 97198 --- [nio-8080-exec-2] h.p.trace.logtrace.ThreadLocalLogTrace : [86b4baba] |-->OrderService.orderItem()2021-11-28 13:54:09.795 INFO 97198 --- [nio-8080-exec-2] h.p.trace.logtrace.ThreadLocalLogTrace : [86b4baba] | |-->OrderRepository.request()2021-11-28 13:54:10.798 INFO 97198 --- [nio-8080-exec-2] h.p.trace.logtrace.ThreadLocalLogTrace : [86b4baba] | |<--OrderRepository.request() time=1003ms2021-11-28 13:54:10.798 INFO 97198 --- [nio-8080-exec-2] h.p.trace.logtrace.ThreadLocalLogTrace : [86b4baba] |<--OrderService.orderItem() time=1003ms2021-11-28 13:54:10.798 INFO 97198 --- [nio-8080-exec-2] h.p.trace.logtrace.ThreadLocalLogTrace : [86b4baba] OrderController.request() time=1005ms

0

Spring 핵심원리 고급편 - Decorator Pattern 2

목차 Post not found: springboot/spring-aop/cglib/cglib-01 Post not found: springboot/spring-aop/dynamic-proxy/dynamic-proxy-02 Post not found: springboot/spring-aop/dynamic-proxy/dynamic-proxy-01 Post not found: springboot/spring-aop/dynamic-proxy/reflection Post not found: springboot/spring-aop/concrete-proxy/concrete-proxy-04 Post not found: springboot/spring-aop/concrete-proxy/concrete-proxy-02 Post not found: springboot/spring-aop/concrete-proxy/concrete-proxy-01 Post not found: springboot/spring-aop/decorator/decorator-02 Post not found: springboot/spring-aop/decorator/decorator-01 Post not found: springboot/spring-aop/proxy-pattern/proxy-04 Post not found: springboot/spring-aop/proxy-pattern/proxy-03 Post not found: springboot/spring-aop/proxy-pattern/proxy-02 Post not found: springboot/spring-aop/proxy-pattern/proxy-01 Post not found: springboot/spring-aop/strategy-pattern/strategy-pattern-01 Post not found: springboot/spring-aop/template-method/template-method-01 Spring 핵심원리 고급편 - Decorator Pattern 적용@Slf4jpublic class TimeDecorator implements Component{ private Component component; public TimeDecorator(Component component) { this.component = component; } @Override public String operation() { log.info("TimeDecorator 실행"); long startTime = System.currentTimeMillis(); String result = component.operation(); long endTime = System.currentTimeMillis(); long resultTime = endTime - startTime; log.info("TimeDecorator 종료 resultTime = {}ms", resultTime); return null; }} @Testvoid decorator2(){ Component realComponent = new RealComponent(); Component messageDecorator = new MessageDecorator(realComponent); Component timeDecorator = new TimeDecorator(messageDecorator); DecoratorPatternClient client = new DecoratorPatternClient(timeDecorator); client.execute();} Decoratro Pattern 은 항상 내부에 꾸며 줄 대상(Component) 가 존재해야 한다.

0

Spring 핵심원리 고급편 - Decorator Pattern 1

목차 Post not found: spring/design-pattern/spring-aop/cglib/cglib-01 Post not found: spring/design-pattern/spring-aop/dynamic-proxy/dynamic-proxy-02 Post not found: spring/design-pattern/spring-aop/dynamic-proxy/dynamic-proxy-01 Post not found: spring/design-pattern/spring-aop/dynamic-proxy/reflection Post not found: spring/design-pattern/spring-aop/concrete-proxy/concrete-proxy-04 Post not found: spring/design-pattern/spring-aop/concrete-proxy/concrete-proxy-02 Post not found: spring/design-pattern/spring-aop/concrete-proxy/concrete-proxy-01 Post not found: spring/design-pattern/spring-aop/decorator/decorator-02 Post not found: spring/design-pattern/spring-aop/decorator/decorator-01 Post not found: spring/design-pattern/spring-aop/proxy-pattern/proxy-04 Post not found: spring/design-pattern/spring-aop/proxy-pattern/proxy-03 Post not found: spring/design-pattern/spring-aop/proxy-pattern/proxy-02 Post not found: spring/design-pattern/spring-aop/proxy-pattern/proxy-01 Post not found: spring/design-pattern/spring-aop/strategy-pattern/strategy-pattern-01 Post not found: spring/design-pattern/spring-aop/template-method/template-method-01 Decorator 패턴 Decorator 패턴 은 기존 객체 수정없이 부가 기능 추가 를 위해 주로 사용하는 디자인 패턴이다. Decorator 패턴은 객체 지향 디자인 원칙 중 하나인 개방-폐쇄 원칙(OCP) 을 따릅니다. 이 패턴을 사용하면 코드의 수정 없이 기존 클래스에 새로운 기능을 추가하거나 기존 기능을 수정할 수 있습니다. Decorator 클래스는 기본 객체와 같은 인터페이스를 사용해 구현되며, 기본 객체를 Wrapping 하여 추가적인 기능을 제공합니다. 이러한 구조는 객체 간의 결합도를 낮추고, 유연성과 확장성을 높입니다. 기존 객체를 감싸는 Wrapper 클래스 를 만들고, Wrapper 클래스에 새로운 기능을 추가하는 방식으로 새로운 기능을 추가하거나 기존 기능을 수정하는데 사용됩니다. Decorator 패턴을 사용하면 객체의 기존 동작을 변경하지 않고도 객체에 새로운 동작을 추가할 수 있습니다. Decorator 패턴의 구성요소 Component 인터페이스나 추상 클래스로 정의된 기본 객체의 공통 인터페이스입니다. ConcreteComponent Component 인터페이스를 구현한 실제 객체입니다. Decorator Component 인터페이스를 구현하며, 기본 객체를 래핑하고 추가적인 기능을 제공하는 추상 클래스입니다. ConcreteDecorator Decorator 추상 클래스를 상속받아 기본 객체를 래핑하고 추가적인 기능을 구현한 실제 객체입니다.

0

Spring 핵심원리 고급편 - Proxy 패턴 컴포넌트 스캔으로 자동 빈 등록

목차 Spring 핵심원리 고급편 - CGLIB Spring 핵심원리 고급편 - Dynamic Proxy 2 Spring 핵심원리 고급편 - Dynamic Proxy 1 Spring 핵심원리 고급편 - 리플렉션 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 적용 2 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 Spring 핵심원리 고급편 - 인터페이스 프록시 1 Spring 핵심원리 고급편 - Decorator Pattern 2 Spring 핵심원리 고급편 - Decorator Pattern 1 Spring 핵심원리 고급편 - Proxy 패턴 컴포넌트 스캔으로 자동 빈 등록 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스 없는 없는 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스와 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 Spring 핵심원리 고급편 - Strategy 패턴 Spring 핵심원리 고급편 - Template Method 패턴 Spring 핵심원리 고급편 - Proxy Pattern 컴포넌트 스캔으로 자동 빈 등록@Repositorypublic class OrderRepositoryV3 { public void save(String itemId) { if(itemId.equals("ex")){ throw new IllegalStateException("예외 발생!"); } sleep(1000); } private void sleep(int millis) { try { Thread.sleep(millis); }catch (InterruptedException ex){ ex.printStackTrace(); } }} @Servicepublic class OrderServiceV3 { private final OrderRepositoryV3 orderRepository; public OrderServiceV3(OrderRepositoryV3 orderRepository) { this.orderRepository = orderRepository; } public void orderItem(String itemId) { orderRepository.save(itemId); }} @RestController@Slf4jpublic class OrderControllerV3 { private final OrderServiceV3 orderService; public OrderControllerV3(OrderServiceV3 orderService) { this.orderService = orderService; } @GetMapping("/v3/request") public String request(String itemId) { orderService.orderItem(itemId); return "ok"; } @GetMapping("/v3/no-log") public String noLog() { return "ok"; }}