코드 를 통 해 자바 의 세 가지 프 록 시 모드 를 빠르게 이해 합 니 다.
프 록 시(Proxy)는 대상 에 대한 별도의 접근 방식,즉 프 록 시 대상 을 통 해 대상 에 접근 하 는 디자인 모델 이다.이렇게 하 는 장점 은 목표 대상 이 실현 되 는 토대 에서 추가 적 인 기능 조작,즉 목표 대상 의 기능 을 확장 할 수 있다 는 것 이다.
여기 서 프로 그래 밍 에 사용 되 는 사상:다른 사람 이 이미 쓴 코드 나 방법 을 마음대로 수정 하지 마 세 요.수정 이 필요 하 다 면 대리 방식 으로 이 방법 을 확장 할 수 있 습 니 다.
UML 그림 은 다음 과 같다.
에이전트 모드
정적 에이전트
정적 프 록 시 를 사용 할 때 인터페이스 나 부모 클래스 를 정의 해 야 합 니 다.피 대리 대상 은 대리 대상 과 함께 같은 인 터 페 이 스 를 실현 하거나 같은 부 류 를 계승 한다.
코드 예제:
interface Source{ void method();}
class OldClass implements Source{
@Override
public void method() {
}
}
class Proxy implements Source{
private Source source = new OldClass();
void doSomething(){}
@Override
public void method() {
new Class1().Func1();
source.method();
new Class2().Func2();
doSomething();
}
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.method();
}
}
정적 에이전트 부족:대리 대상 은 목표 대상 과 같은 인터페이스 나 부모 클래스 를 실현 해 야 하기 때문에 대리 클래스 가 너무 많 습 니 다.또한 인터페이스 가 증가 하면 대상 과 대리 대상 을 모두 유지 해 야 한다.
동적 에이전트
JDK 에서 동적 프 록 시 클래스 는 java.lang.reflect.Proxy.newProxyInstance 방법 만 사용 하면 됩 니 다.이 방법 은 세 개의 인 자 를 받 아야 합 니 다.완전한 쓰기 방법 은:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
이 방법 은 Proxy 클래스 에서 정적 방법 이 고 받 은 세 개의 매개 변 수 는 다음 과 같 습 니 다.
/**
*
*/
interface IUserDao {
void save();
}
/**
*
*
*/
class UserDao implements IUserDao {
public void save() {
System.out.println("---- !----");
}
}
/**
*
* ,
*/
class ProxyFactory {
//
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
//
public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println(" ");
//
Object returnValue = method.invoke(target, args);
System.out.println(" ");
return returnValue;
});
}
}
/**
*
*/
class App {
public static void main(String[] args) {
//
IUserDao target = new UserDao();
// System.out.println(target.getClass());
// ,
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
// System.out.println(proxy.getClass());
//
proxy.save();
}
}
메모:대리 대상 은 인 터 페 이 스 를 실현 할 필요 가 없 지만 목표 대상 은 반드시 인 터 페 이 스 를 실현 해 야 합 니 다.그렇지 않 으 면 동적 대 리 를 사용 할 수 없습니다.cglib 에이전트
정적 에이전트 와 동적 에이전트 모델 은 모두 목표 대상 에 게 인 터 페 이 스 를 실현 하도록 요구 하지만 가끔 은 목표 대상 이 하나의 단독 대상 일 뿐 어떠한 인터페이스 도 실현 하지 못 한다.이 럴 때 목표 대상 서브 클래스 의 방식 으로 대 리 를 실현 할 수 있다.이런 방법 을 Cglib 대리 라 고 부른다.
Cglib 대 리 는 하위 클래스 에이전트 라 고도 부 릅 니 다.메모리 에 하위 클래스 대상 을 구축 하여 대상 기능 에 대한 확장 을 실현 합 니 다.Cglib 는 강력 한 고성능 코드 생 성 패키지 로 실행 기간 에 자바 류 를 확장 하고 자바 인 터 페 이 스 를 실현 할 수 있 습 니 다.그것 은 많은 AOP 의 프레임 워 크 에 의 해 광범 위 하 게 사용 되 고 방법 을 제공 하 는 interception(차단),예 를 들 어 모두 가 알 고 있 는 Spring AOP 등 이다.
cglib 패키지 의 밑바닥 은 작고 빠 른 바이트 처리 프레임 ASM 을 사용 하여 바이트 코드 를 변환 하고 새로운 클래스 를 생 성 합 니 다.cglib 하위 에이전트 가 주의해 야 할 것 은:
1.Cglib 의 jar 파일 을 도입 해 야 하지만 Spring 의 핵심 패키지 에는 Cglib 기능 이 포함 되 어 있 기 때문에 spring-core-xxx.jar 를 직접 도입 하면 됩 니 다.(스프링 3.2 이후 에 야 Cglib 포함)
2.대리 클래스 는 final 일 수 없습니다.그렇지 않 으 면 잘못 보고 합 니 다.
3.목표 대상 의 방법 이 final/static 이면 차단 되 지 않 습 니 다.즉,목표 대상 의 추가 업무 방법 을 수행 하지 않 습 니 다.
코드 예제:
public class test {
public static void main(String[] args) {
//
UserDao target = new UserDao();
//
UserDao proxy = (UserDao) new ProxyFactory(target).getProxyInstance();
//
proxy.save();
}
}
/**
* ,
*/
class UserDao {
public void save() {
System.out.println("---- !----");
}
}
/**
* Cglib
* UserDao
*/
class ProxyFactory implements MethodInterceptor {
//
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
//
public Object getProxyInstance() {
//1.
Enhancer en = new Enhancer();
//2.
en.setSuperclass(target.getClass());
//3.
en.setCallback(this);
//4. ( )
return en.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println(" ...");
//
Object returnValue = method.invoke(target, args);
System.out.println(" ...");
return returnValue;
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.