일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- pointcut
- 스프링
- java
- Spring Boot
- 스프링 핵심 기능
- SpringBoot
- springdatajpa
- db
- Exception
- JPQL
- 알고리즘
- transaction
- Proxy
- 그리디
- JDBC
- kotlin
- 스프링 핵심 원리
- Android
- jpa
- 백준
- spring
- http
- Thymeleaf
- Greedy
- 자바
- 인프런
- QueryDSL
- Servlet
- 김영한
- AOP
- Today
- Total
목록인프런 (528)
개발자되기 프로젝트
앞선 방법들은 자기 자신을 주입하거나 또는 Provider 를 사용해야 하는 것 처럼 조금 어색한 모습을 만들었다. 가장 나은 대안은 내부 호출이 발생하지 않도록 구조를 변경하는 것이다. 실제 이 방법을 가장 권장한다. 1. Internal 클래스 분리 /** * 구조를 변경(분리) */ @Slf4j @Component public class CallServiceV3 { private final InternalService internalService; public CallServiceV3(InternalService internalService) { this.internalService = internalService; } public void external(){ log.info("call exter..
앞서 생성자 주입이 실패하는 이유는 자기 자신을 생성하면서 주입해야 하기 때문이다. 이 경우 수정자 주입을 사용하거나 지금부터 설명하는 지연 조회를 사용하면 된다. 스프링 빈을 지연해서 조회하면 되는데, ObjectProvider(Provider) , ApplicationContext 를 사용 1. ApplicationContext @Slf4j @Component public class CallServiceV2 { private final ApplicationContext applicationContext; public CallServiceV2(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } p..
내부 호출을 해결하는 가장 간단한 방법은 자기 자신을 의존관계 주입 받는 것. 오? 1. 자기 자신 주입 @Slf4j @Component public class CallServiceV1 { private CallServiceV1 callServiceV1; /** * 생성자 주입은 순환 사이클을 만들기 때문에 실패한다. * 수정자(setter) 주입도 스프링 부트 2.6붙 막힘 --> 순환참조 금지 * 순환참조를 해결하기 위해 application.properties에 아래 파일 추가 * spring.main.allow-circular-references=true */ @Autowired public void setCallServiceV1(CallServiceV1 callServiceV1) { this.c..
1. 스프링은 프록시 방식의 AOP를 사용한다. 따라서 AOP를 적용하려면 항상 프록시를 통해서 대상 객체(Target)을 호출해야 한다. 이렇게 해야 프록시에서 먼저 어드바이스를 호출하고, 이후에 대상 객체를 호출한다. 만약 프록시를 거치지 않고 대상 객체를 직접 호출하게 되면 AOP가 적용되지 않고, 어드바이스도 호출되지 않는다. 2. AOP를 적용하면 스프링은 대상 객체 대신에 프록시를 스프링 빈으로 등록한다. 따라서 스프링은 의존관계 주입시에 항상 프록시 객체를 주입한다. 프록시 객체가 주입되기 때문에 대상 객체를 직접 호출하는 문제는 일반적으로 발생하지 않는다. 하지만 대상 객체의 내부에서 메서드 호출이 발생하면 프록시를 거치지 않고 대상 객체를 직접 호출하는 문제가 발생한다. 3. 내부 호출이..
@Retry 애노테이션이 있으면 예외가 발생했을 때 다시 시도해서 문제를 복구한다. 1. @Retry Retry방식을 사용할 때 항상 재시도 횟수가 정해져 있어야 함. @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Retry { int value() default 3; //Retry는 항상 재시도 횟수가 있어야함.. } 2. RetryAspect @Slf4j @Aspect public class RetryAspect { /* @Around("@annotation(hello.aop.exam.annotation.Retry)") public Object doRetry(ProceedingJoinPoint join..
@Trace 가 메서드에 붙어 있으면 호출 정보가 출력되도록 하자. 1. @Trace @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Trace { } 2. TraceAspect @Slf4j @Aspect public class TraceAspect { @Before("@annotation(hello.aop.exam.annotation.Trace)") public void doTrace(JoinPoint joinPoint){ Object[] args = joinPoint.getArgs(); log.info("[trace] {}, args={}", joinPoint.getSignature(), args); }..
지금까지 학습한 내용을 활용해서 유용한 스프링 AOP를 만들어보자. @Trace 애노테이션으로 로그 출력하기 @Retry 애노테이션으로 예외 발생시 재시도 하기 1. Repository @Repository public class ExamRepository { private static int seq = 0; /** * 5번에 한 번 실패하는 요청 */ public String save(String itemId){ seq++; if (seq%5 == 0){ throw new IllegalStateException("예외 발생"); } return "ok"; } } 2. Service @Service @RequiredArgsConstructor public class ExamService { private..
1. 정의 this : 스프링 빈 객체(스프링 AOP 프록시)를 대상으로 하는 조인 포인트 target : Target 객체(스프링 AOP 프록시가 가르키는 실제 대상)를 대상으로 하는 조인 포인트 2. 설명 this , target 은 다음과 같이 적용 타입 하나를 정확하게 지정해야 한다. this(hello.aop.member.MemberService) target(hello.aop.member.MemberService) * 같은 패턴을 사용할 수 없다. 부모 타입을 허용한다. 3. this vs target 스프링에서 AOP를 적용하면 실제 target 객체 대신에 프록시 객체가 스프링 빈으로 등록된다. this 는 스프링 빈으로 등록되어 있는 프록시 객체를 대상으로 포인트컷을 매칭한다. Targe..