자바 면접 흔 한 패턴 문제---대리 모드
정적 에이전트 역할 분석:
세입 자 는 집주인 의 집 을 중개업 자의 손 을 통 해 임대 하고,대리 대상 중개업 자 는 세입 자 를 찾 아 전 세 를 구하 고 중개 비용 을 받 아야 한다.
코드 구현:
Rent.java
즉 추상 적 인 역할
// :
public interface Rent {
public void rent();
}
Host.java
즉 실제 캐릭터
// : ,
public class Host implements Rent{
public void rent() {
System.out.println(" ");
}
}
Proxy.java
즉 대리 역할
// :
public class Proxy implements Rent {
private Host host;
public Proxy() { }
public Proxy(Host host) {
this.host = host;
}
//
public void rent(){
seeHouse();
host.rent();
fare();
}
//
public void seeHouse(){
System.out.println(" ");
}
//
public void fare(){
System.out.println(" ");
}
}
Client.java
호출 자,즉 고객
// , !
public class Client {
public static void main(String[] args) {
//
Host host = new Host();
//
Proxy proxy = new Proxy(host);
// !
proxy.rent();
}
}
정적 에이전트 의 단점:프 록 시 클래스 를 수 동 으로 만들어 야 합 니 다.프 록 시 대상 이 많 으 면 프 록 시 클래스 도 점점 많아 집 니 다.
이 문 제 를 해결 하기 위해 동적 대리 가 생 겼 습 니 다!
2.동적 에이전트
동적 대리 하면 면접 을 볼 때 동적 대리 의 두 가지 실현 방식 을 물 어 볼 것 이다.
먼저 공공
UserService
인터페이스 와UserServiceImpl
실현 유형 을 살 펴 보 자.
/**
* @author csp
* @date 2021-06-03
*/
public interface UserService {
/**
*
*/
void login();
/**
*
*/
void logout();
}
/**
* @author csp
* @date 2021-06-03
*/
public class UserServiceImpl implements UserService{
@Override
public void login() {
System.out.println(" ...");
}
@Override
public void logout() {
System.out.println(" ...");
}
}
JDK 동적 에이전트코드 는 다음 과 같 습 니 다:
/**
* @author csp
* @date 2021-06-03
*/
public class JDKProxyFactory implements InvocationHandler {
// ( )
private Object target;
public JDKProxyFactory(Object target) {
super();
this.target = target;
}
/**
*
*
* @return
*/
public Object createProxy() {
// 1.
ClassLoader classLoader = target.getClass().getClassLoader();
// 2.
Class<?>[] interfaces = target.getClass().getInterfaces();
// 3. invocationHandler
Object newProxyInstance = Proxy.newProxyInstance(classLoader, interfaces, this);
return newProxyInstance;
}
/**
*
*
* @param proxy .
* @param method
* @param args
* @return
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK : / ......");
Object invoke = method.invoke(target, args);
System.out.println("JDK : / ......");
return invoke;
}
public static void main(String[] args) {
// 1.
UserServiceImpl userService = new UserServiceImpl();
// 2.
JDKProxyFactory jdkProxyFactory = new JDKProxyFactory(userService);
// 3. ,
UserService userServiceProxy = (UserService) jdkProxyFactory.createProxy();
userServiceProxy.login();
System.out.println("==================================");
userServiceProxy.logout();
}
}
출력 결 과 는 다음 과 같 습 니 다.JDK 동적 에이전트:로그 인/로그아웃 전 논리 검사...
사용자 로그 인...
JDK 동적 에이전트:로그 인/로그 인 후 로그 인쇄...
==================================
JDK 동적 에이전트:로그 인/로그아웃 전 논리 검사...
사용자 로그 인 출시...
JDK 동적 에이전트:로그 인/로그 인 후 로그 인쇄...
CGLIB 동적 에이전트
코드 는 다음 과 같 습 니 다:
/**
* @author csp
* @date 2021-06-03
*/
public class CglibProxyFactory implements MethodInterceptor {
// ( )
private Object target;
//
public CglibProxyFactory(Object target) {
super();
this.target = target;
}
/**
*
*
* @return
*/
public Object createProxy() {
// 1. Enhancer
Enhancer enhancer = new Enhancer();
// 2. class
enhancer.setSuperclass(target.getClass());
// 3.
enhancer.setCallback(this);
return enhancer.create();
}
/**
*
* @param o
* @param method
* @param objects
* @param methodProxy
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib : / ......");
Object invoke = method.invoke(target, objects);
System.out.println("cglib : / ......");
return invoke;
}
public static void main(String[] args) {
// 1.
UserServiceImpl userService = new UserServiceImpl();
// 2.
CglibProxyFactory cglibProxyFactory = new CglibProxyFactory(userService);
// 3. ,
UserService userServiceProxy = (UserService) cglibProxyFactory.createProxy();
userServiceProxy.login();
System.out.println("==================================");
userServiceProxy.logout();
}
}
테스트 결 과 는 다음 과 같다.cglib 동적 에이전트:로그 인/로그 인 전 논리 검사...
사용자 로그 인...
cglib 동적 에이전트:로그 인/로그 인 후 로그 인쇄...
==================================
cglib 동적 에이전트:로그 인/로그 인 전 논리 검사...
사용자 로그 인 출시...
cglib 동적 에이전트:로그 인/로그 인 후 로그 인쇄...
면접 문제 1:JDK 동적 에이전트 와 CGLIB 동적 에이전트 의 차이 점 은?
① JDK 동적 대 리 는 본질 적 으로 피 대리 대상 의 인 터 페 이 스 를 실현 하 는 것 이 고 CGLib 는 본질 적 으로 피 대리 대상 을 계승 하여 이 를 덮어 쓰 는 방법 이다.
② JDK 동적 에이 전 트 는 인 터 페 이 스 를 구현 한 클래스 생 성 에이전트 에 만 적용 되 며,CGLib 는 이 제한 이 없다.그러나 CGLib 는 계승 을 사용 하여 실현 되 기 때문에 CGLib 는
final
클래스,private
방법 과static
방법 을 대리 할 수 없다.③ JDK 동적 대 리 는 JDK 에서 자체 적 으로 가 져 온 것 으로 CGLib 동적 대 리 는 제3자
jar
가방 을 도입 해 야 한다.④ 호출 에이전트 방법 에서 JDK 동적 대 리 는 반사 체 제 를 통 해 호출 되 고 CGLib 는 FastClass 체 제 를 통 해 직접 호출 된다.(한 편의 글 을 보고 FastClass 의 간단 한 이 해 는 index 아래 표 시 를 인삼 으로 사용 하 는 것 이 라 고 소개 했다.호출 할 방법 을 직접 찾 아 호출 할 수 있다)
성능 상 JDK 1.7 이전 에는 FastClass 메커니즘 을 사 용 했 기 때문에 CGLib 는 JDK 보다 실행 효율 이 빨 랐 지만,JDK 동적 에이전트 가 계속 최적화 되면 서 JDK 1.7 부터 JDK 동적 에이전트 가 CGLib 보다 훨씬 빨 라 졌 다.
면접 문제 2:JDK 동적 대 리 는 왜 인 터 페 이 스 를 실현 한 클래스 생 성 대리 만 가능 합 니까?
근본 적 인 원인 은 JDK 동적 에이 전 트 를 통 해 생 성 된 클래스 가 프 록 시 클래스 를 계 승 했 기 때문에 더 이상 클래스 에 대한 에이 전 트 를 계승 할 수 없습니다.
총결산
글 은 정 해진 시간 에 업데이트 되 지 않 습 니 다.가끔 은 하루 에 몇 편 을 더 업데이트 합 니 다.만약 에 지식 을 공 고 히 하 는 데 도움 이 된다 면 3 연 대 를 지원 하 세 요.나중에 조금씩 업데이트 할 것 입 니 다!저희 의 또 다른 콘 텐 츠 에 많은 관심 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.