일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 스프링환경설정
- 베주계수
- 자바 스트링
- replaceAll()
- 최소공배수
- 자바 최소공배수
- 유클리드호제법
- while과 two-pointer
- string
- 래퍼타입
- string과 stringbuilder
- toLowerCase()
- stringbuilder의 reverse()
- 모던자바
- 자바 유클리드
- 자바 최대공약수
- 동일성과 동등성
- Git사용법
- islowercase()
- 프로그래머스 레벨1
- ineer join
- 최대공약수
- isuppercase()
- 최대공약수와 최소공배수
- sql 데이터형 변환
- addDoc
- StringBuilder
- 스프링
- git 컨벤션
- 스프링뼈대
- Today
- Total
주노 님의 블로그
[Spirng] 8. AOP(관점 지향 프로그래밍), 프록시 본문
시작하기에 앞서
아래 내용은 김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB접근기술에서 발췌한 내용입니다.
강의자료 일부를 발췌하는건 괜찮다고 하셨다.
무료강의로 지식을 공유해주신 김영한님께 다시한번 감사의 인사를 올리겠습니다
(_ _) (유료도 샀어요!)
AOP(Aspect Oriented Programming)란?
공통 관심 사항과 핵심관심 사항을 분리하는 것이다
1. 모든 메서드의 호출 시간을 측정하고 싶다면.
join 메서드 실행 시간 확인하기
public Long join(Member member)
{
//메서드 실행 시간 확인하기
long start = System.currentTimeMillis();
try{
//조건 추가 : 같은 이름이 있는 중복 회원은 안된다!
Optional<Member> result = memberRepository.findByName(member.getName());
//기존 멤버가 있으면, if null이 아니면<< 아래 에러를 던져준다
// null일 가능성이 있으면 요즘은 optional로 감싼다. result.orElseGet() << 있으면? 없으면?
result.ifPresent(m -> { throw new IllegalStateException("이미 존재하는 회원이다"); });
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}finally
{
long finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("join = " + timeMs + " ms");
}
}
메서드 처음부분에 strat를
끝부분에 finish를 부착해서
시간을 측정한다.
이렇게 일일히 시간 조회 로직을 구현해야하나? >> AOP사용으로 해결할 수 있다.
시간 조회는 핵심 관심 사항(주요한 비즈니스 로직)이 아니다
메서드 실행 시간은 공통 관심 사항(여러 모듈이나 메서드에 발생하는 로직)이다.
핵심 관심 사항과 섞여있으면 유지보수에 어려움이 생긴다.
공통 관심사항은 별도의 공통 로직으로 만들기 어렵다.
AOP사용하는법
공통 관심사항을 따로 분리하여 원하는 곳에 공통 관심사항을 적용케 하는것이다.
1. aop 클래스 생성
시간을 측정하는 로직인 TimeTraceAop를 만든다
//aop는 aspect 어노테이션 사용해야함
@Component
@Aspect
public class TimeTraceAop {
//타게팅 하는법 : 내 프로젝트의 하위에 모두 적용한다.
@Around("execution(* springProject.hello_spring..*(..)) && !target(springProject.hello_spring.member_management.SpringConfig)")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable
{
long startTime = System.currentTimeMillis();
System.out.println("START : " + joinPoint.toString());
try {
return joinPoint.proceed();
} finally {
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println("End : " + joinPoint.toString() + " " + elapsedTime + "ms");
System.out.println("------------------------------------------------------------------------------------------------------");
}
}
}
@Around는 타게팅 하는법으로 execution을 정의하면 내가 이 아래 패키지에서 AOP를 실행하겠다
이고, 이렇게만 하면 순환 참조 오류가 발생할 수 있는데, 그 이유는 SpringConfig 파일이 저 파일들 하위에 있을 경우
또 SpringConfig는 또 참조하게 된다
aop의 동작 원리
aop를 사용하기전에는 컨트롤러에서 서비스를 호출할 때 의존관계로 호출했다
aop를 적용했을때
aop를 적용한다면 service는 프록시라는 가짜 객체를 생성한다
controller는 프록시를 호출하게 되고, joinPoint.proceed()를 사용하면
프록시는 실제 객체를 가르킨다
프록시란
실제 클래스를 상속 받아서 만들어지는 가짜 객체이다
하이버네이트가 자동생성을 하며, 사용하는 입장에서는 프록시인지, 아닌지 모른다
프록시 객체는 실제 데이터를 저장하지 않지만, 실제 데이터를 저장하는 참조만을 보관한다
@Autowired
public MemberController(MemberService memberService)
{
this.memberService = memberService;
System.out.println("MemberService" + memberService.getClass());
}
memberService를 주입하는 단계에서 getClass를하면
MemberServiceclass springProject.hello_spring.member_management.service.MemberService$$SpringCGLIB$$0
SpringCGLIB$$0<< 이런 프록시가 호출되게 된다.
'공부 > Spring' 카테고리의 다른 글
[JPA] JPA에 대해서 (0) | 2024.08.19 |
---|---|
[Spring] 객체지향 설계의 5가지 원칙 (SOLID) (0) | 2024.07.31 |
[Spirng] 7. Spring 데이터베이스 연동 - 스프링 데이터 Jpa (0) | 2024.07.30 |
[Spirng] 7. Spring 데이터베이스 연동 - JPA (0) | 2024.07.29 |
[Spirng] 7. Spring 데이터베이스 연동 - JDBCTemplate (0) | 2024.07.29 |