| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 객체지향
- 문자열
- Spring
- 모던자바
- BOJ
- 자바
- test
- OS
- 알고리즘
- Reflection
- MST
- Deadlock
- java
- 최소 신장 트리
- 스프링 시큐리티
- 프록시
- Junit5
- 운영체제
- CS
- 다이나믹 프록시
- proxy
- Python
- 리플렉션
- spring security
- 스프링
- redis
- 파이썬
- 약수
- 모던 자바 인 액션
- 백준
Archives
- Today
- Total
Dev 달팽이 @_''
Java - 클래스의 프록시 본문
Java - 클래스의 프록시
- 서브 클래스를 만들 수 있는 라이브러리를 사용하여 프록시를 생성 가능
- CGlib을 이용하는 방법과 ByteBuddy를 이용하는 방법이 있음
CGlib
- https://github.com/cglib/cglib/wiki
- 스프링, 하이버네이트가 사용하는 라이브러리
- 버전 호환성이 좋지 않아서 서로 다른 라이브러리 내부에 내장된 형태로 제공되기도 함
- 아래의 의존 추가
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
BookServiceTest.java
@Test
public void diWithCglib(){
MethodInterceptor handler = new MethodInterceptor() {
BookService bookService = new BookService();
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if(method.getName().equals("rent"))
System.out.println("This is Proxy");
Object invoke = method.invoke(bookService, args);
return invoke;
}
};
BookService bookService = (BookService) Enhancer.create(BookService.class, handler);
Book book = new Book();
book.setTitle("Spring");
bookService.rent(book);
bookService.returnBook(book);
}
- Interceptor handler를 이용하여 BookService 객체가 들어오면 어떤 작업을 할 지 정해줌
ByteBuddy
- 바이트코드 조작 뿐 아니라 런타임(다이나믹) 프록시를 만들 때도 사용 가능
BookServiceTest.java
@Test
public void diWithByteBuddy() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<? extends BookService> proxyClass = new ByteBuddy().subclass(BookService.class)
.method(named("rent")).intercept(InvocationHandlerAdapter.of(new InvocationHandler() {
BookService bookService = new BookService();
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("This is proxy");
Object invoke = method.invoke(bookService, args);
return invoke;
}
}))
.make().load(BookService.class.getClassLoader()).getLoaded();
BookService bookService = proxyClass.getConstructor(null).newInstance();
Book book = new Book();
book.setTitle("Spring");
bookService.rent(book);
bookService.returnBook(book);
}
- 함수를 intercept하여 InvocationHandler를 이용해 어떤 작업을 할 지 정해줌
서브 클래스를 만드는 방법의 단점
- 상속을 사용하지 못하는 경우 프록시를 만들 수 없다.
- Private 생성자만 있는 경우
- Final 클래스인 경우
- 인터페이스가 있을 때는 인터페이스의 프록시를 만들어 사용할 것
다이나믹 프록시 정리
- 다이나믹 프록시
- 런타임에 인터페이스 또는 클래스의 프록시 인스턴스 또는 클래스를 만들어 사용하는 프로그래밍 기법
- 다이나믹 프록시 사용처
- 스프링 데이터 JPA
- 스프링 AOP
- Mockito
- 하이버네이트 lazy initialization
- ...
'Java&Spring > 더 자바, 코드를 조작하는 다양한 방법' 카테고리의 다른 글
| Java - 애노테이션 프로세서 (0) | 2022.01.10 |
|---|---|
| Java - 다이나믹 프록시 (0) | 2022.01.09 |
| Java - 프록시 패턴 (0) | 2022.01.09 |
| Java - 간단한 DI 프레임워크 만들기 (0) | 2022.01.09 |
| Java - 리플렉션(클래스 정보 수정 또는 실행) (0) | 2022.01.09 |