>  기사  >  Java  >  Java의 프록시 패턴

Java의 프록시 패턴

王林
王林원래의
2023-06-07 23:22:063303검색

Java의 프록시 패턴

프록시는 객체가 다른 객체의 형태로 나타나고 프록시 객체를 통해 원본 객체에 접근할 수 있도록 하는 디자인 패턴입니다. 프록시는 많은 응용 프로그램에서 널리 사용되며 그 중 가장 일반적인 것은 원격 개체 호출을 구현하고 네트워크에 로그인하는 것입니다.

Java에서 프록시 패턴을 사용하는 예도 많이 있습니다. Java의 프록시 패턴은 주로 다음 세 가지 방식으로 구현됩니다.

  1. 정적 프록시

정적 프록시는 컴파일 단계에서 프록시 클래스를 생성하여 구현됩니다. 프록시 클래스와 원본 클래스는 동일한 인터페이스를 구현하고, 프록시 클래스는 원본 클래스의 메서드를 호출하여 자체 메서드를 구현합니다. 정적 프록시의 장점은 상대적으로 간단하고 직관적이라는 점이지만, 프록시 클래스를 수동으로 작성해야 한다는 단점이 있습니다. 프록시 메서드를 추가하거나 수정하는 경우 이에 따라 프록시 클래스도 수정해야 합니다.

다음은 간단한 정적 프록시 예입니다.

// 定义接口
interface UserManager {
    void add();
    void delete();
}

// 原始类
class UserManagerImpl implements UserManager {
    public void add() {
        System.out.println("添加用户");
    }

    public void delete() {
        System.out.println("删除用户");
    }
}

// 代理类
class UserManagerProxy implements UserManager {
    private UserManager userManager;

    public UserManagerProxy(UserManager userManager) {
        this.userManager = userManager;
    }

    public void add() {
        System.out.println("记录日志...");
        userManager.add();
        System.out.println("记录日志...");
    }

    public void delete() {
        System.out.println("记录日志...");
        userManager.delete();
        System.out.println("记录日志...");
    }
}

// 客户端代码
UserManager userManager = new UserManagerImpl();
UserManagerProxy userManagerProxy = new UserManagerProxy(userManager);
userManagerProxy.add();
userManagerProxy.delete();
  1. 동적 프록시

동적 프록시는 런타임 시 리플렉션 메커니즘을 통해 프록시 클래스를 생성하는 것입니다. 정적 프록시와 달리 동적 프록시는 여러 인터페이스를 프록시할 수 있으며 프록시 클래스를 수동으로 작성할 필요가 없습니다. 동적 프록시의 장점은 더 유연하다는 점이지만, 단점은 성능에 일정한 영향을 미친다는 것입니다.

다음은 간단한 동적 프록시 예입니다.

// 定义接口
interface UserManager {
    void add();
    void delete();
}

// 原始类
class UserManagerImpl implements UserManager {
    public void add() {
        System.out.println("添加用户");
    }

    public void delete() {
        System.out.println("删除用户");
    }
}

// 代理类
class MyInvocationHandler implements InvocationHandler {
    private UserManager userManager;

    public MyInvocationHandler(UserManager userManager) {
        this.userManager = userManager;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("记录日志...");
        Object result = method.invoke(userManager, args);
        System.out.println("记录日志...");
        return result;
    }
}

// 客户端代码
UserManager userManager = new UserManagerImpl();
InvocationHandler handler = new MyInvocationHandler(userManager);
UserManager proxy = (UserManager) Proxy.newProxyInstance(
    userManager.getClass().getClassLoader(),
    userManager.getClass().getInterfaces(),
    handler
);
proxy.add();
proxy.delete();
  1. CGLIB 프록시

CGLIB 프록시는 원래 클래스의 하위 클래스를 생성하여 구현됩니다. CGLIB 프록시는 인터페이스를 구현하지 않고 동적 프록시보다 빠른 클래스를 프록시할 수 있습니다. 그러나 CGLIB 프록시에는 원래 클래스가 최종 클래스일 수 없고 모든 메서드가 최종 클래스가 아니어야 한다는 단점도 있습니다.

다음은 간단한 CGLIB 프록시 예입니다.

// 原始类
class UserManager {
    public void add() {
        System.out.println("添加用户");
    }

    public void delete() {
        System.out.println("删除用户");
    }
}

// 代理类
class MyMethodInterceptor implements MethodInterceptor {
    private UserManager userManager;

    public MyMethodInterceptor(UserManager userManager) {
        this.userManager = userManager;
    }

    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("记录日志...");
        Object result = method.invoke(userManager, args);
        System.out.println("记录日志...");
        return result;
    }
}

// 客户端代码
UserManager userManager = new UserManager();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserManager.class);
enhancer.setCallback(new MyMethodInterceptor(userManager));
UserManager proxy = (UserManager) enhancer.create();
proxy.add();
proxy.delete();

요약

프록시 패턴은 변경하지 않고 원래 클래스에 추가 기능을 제공하는 일반적으로 사용되는 디자인 패턴입니다. Java에는 프록시 패턴을 구현하는 세 가지 방법이 있습니다: 정적 프록시, 동적 프록시 및 CGLIB 프록시. 다양한 구현 방법에는 장점과 단점이 있으며 특정 상황에 따라 선택하고 사용할 수 있습니다.

위 내용은 Java의 프록시 패턴의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.