>  기사  >  Java  >  Java 프록시 모드를 적용하는 방법

Java 프록시 모드를 적용하는 방법

WBOY
WBOY앞으로
2023-05-06 12:52:061004검색

1. 에이전시 모델 소개

에이전시 모델은 실제로 자신이 하고 싶은 일이 없으면 대신 해줄 사람을 찾는 것입니다. . 프로그램에서는 객체에 대한 대체물을 제공하고, 대체물이 대상 객체에 접근하도록 제어하는데, 이것의 장점은 대상 객체가 제공하는 기능 외에 대체물도 더 많은 일을 할 수 있다는 점이다. 를 통해 대상 개체의 기능을 확장할 수 있습니다. 프록시는 원격 개체, 생성 비용이 많이 드는 개체 또는 보안 제어가 필요한 개체일 수 있습니다.

프록시 모드는 주로 다음 세 가지 유형으로 나뉩니다.

  • 정적 프록시

  • 동적 프록시(JDK 프록시, 인터페이스 프록시라고도 함)

  • cglib 프록시(동적 프록시 범주에도 속함) )

2. 정적 프록시

「1. 정적 프록시 소개:」

정적 프록시를 사용할 때는 인터페이스 또는 상위 클래스를 정의해야 합니다. 동일한 인터페이스를 사용하거나 동일한 상위 클래스를 상속받습니다.

『2. 적용 예:』

  • 인터페이스 정의: TeacherDao

  • 프록시 개체를 정의합니다. TeacherDaoImpl, 구현해야 함 TeacherDao

  • 프록시 객체 정의: TeacherDaoProxy 또한 구현해야 합니다. TeacherDao

  • 전화해 TeacherDaoImpl방법, 먼저 만들어야 합니다. TeacherDaoProxy객체를 만든 다음 생성 TeacherDaoImpl이의, 의지 TeacherDaoImpl물건이 다음에게 전달됩니다. TeacherDaoProxy객체를 만든 다음 관련 메서드를 조정합니다.

코드 구현:
  • TeacherDao.java:

<code>public interface TeacherDao {<br>    void teach();<br>}<br></code>
  • TeacherDaoImpl.java:

<code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
  • TeacherDaoProxy.java:

<code>public class TeacherDaoProxy implements TeacherDao {<br>    <br>    private TeacherDao target; // 被代理的对象<br>    <br>    public TeacherDaoProxy(TeacherDao target){<br>        this.target = target;<br>    }<br>    <br>    @Override<br>    public void teach() {<br>        System.out.println("代理开始");<br>        // 这里可以写一些额外的逻辑,以达到扩展被代理对象的目的,相当于spring的前置通知<br>        target.teach();<br>        // 这里也可以写一些额外的逻辑,以达到扩展被代理对象的目的,相当于spring的后置通知<br>        System.out.println("代理结束");<br>    }<br>}<br></code>
  • Client.java: 프록시 객체 호출

<code>public class Client {<br><br>    public static void main(String[] args){<br>        // 创建被代理的对象<br>        TeacherDao target = new TeacherDaoImpl();<br>        // 创建代理对象<br>        TeacherDaoProxy proxy = new TeacherDaoProxy(target);<br>        // 通过代理对象调用方法<br>        proxy.teach();<br>    }<br>}<br></code>

『3. 정적 프록시의 장점과 단점:』

  • 장점: 프록시 객체를 수정하지 않고도 프록시 객체를 확장하고 일부 개선할 수 있습니다.

  • 단점: 동일한 인터페이스를 구현하거나 상속해야 합니다. 동일한 상위 클래스이므로 많은 프록시 클래스가 있게 되며 인터페이스나 상위 클래스가 변경되면 프록시 객체와 프록시 객체를 모두 유지해야 합니다

3. 동적 프록시(JDK 프록시)

「1. 동적 프록시 소개: "

프록시 객체는 인터페이스를 구현할 필요가 없지만 프록시 객체는 여전히 인터페이스를 구현해야 합니다. 동적 프록시 객체 생성에서는 JDK API와 리플렉션 패키지 아래의 Proxy 클래스를 사용하여 메모리에 프록시 객체를 동적으로 구축합니다.

『2.java.lang.reflect.Proxy:』

이 클래스에는 다음과 같이 세 개의 매개변수를 받는 newProxyInstance 메소드가 있습니다.

<code>static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)<br></code>

『3. 적용 예:』

  • 인터페이스 정의: TeacherDao

  • 프록시 객체 정의: TeacherDao를 구현해야 하는 TeacherDaoImpl

  • getProxyInstance 메소드가 있는 프록시 팩토리 ProxyFactory 정의 프록시 객체를 전달한 다음 프록시 객체 인스턴스를 반환하고 프록시 객체를 통해 프록시 객체의 메소드를 호출합니다.

코드 구현:
  • TeacherDao.java:

<code>public interface TeacherDao {<br>    void teach();<br>}<br></code>
  • TeacherDaoImpl.java:

<code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
  • ProxyFactory.java

<code>public class ProxyFactory {<br><br>    private Object target; // 被代理的对象<br><br>    public ProxyFactory(Object target){<br>        this.target = target;<br>    }<br><br>    // 给被代理的对象生成一个代理对象<br>    public Object getProxyInstance(){<br>        // 参数1:指定被代理对象的类加载器<br>        // 参数2:被代理对象实现的接口类型<br>        // 参数3:事件处理,执行被代理对象的方法<br>        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {<br>            @Override<br>            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br>                System.out.println("JDK代理开始");<br>                // 调用方法,args的方法的参数<br>                Object returnValue = method.invoke(target, args);<br>                System.out.println("JDK代理结束");<br>                // 将执行结果return<br>                return returnValue;<br>            }<br>        });<br>    }<br>}<br></code>
  • Client.java: 프록시를 통한 호출 방법

<code>public class Client {<br><br>    public static void main(String[] args){<br>        // 创建被代理的对象<br>        TeacherDao target = new TeacherDaoImpl();<br>        // 创建代理对象<br>        TeacherDao proxy = (TeacherDao) new ProxyFactory(target).getProxyInstance();<br>        // 通过代理对象调用被代理对象的方法<br>        proxy.teach();<br>    }<br>}</code>  
  

IV. cglib 프록시

「1. cglib 프록시 소개:」

정적 프록시 및 동적 프록시, 프록시된 객체는 인터페이스를 구현해야 합니다. 클래스가 인터페이스를 구현하지 않는 경우 cglib 프록시를 사용해야 합니다. cglib 에이전트는 서브클래스 에이전트라고도 하며 프록시 객체를 확장하기 위해 메모리에 서브클래스 객체를 구축합니다. cglib 에이전트의 맨 아래 계층은 ASM이라는 바이트코드 처리 프레임워크를 사용하여 바이트코드를 변환하고 에이전트를 구현하기 위한 새 클래스를 생성합니다. 프록시된 클래스는 최종 클래스일 수 없습니다. 그렇지 않으면 오류가 보고됩니다. 프록시 개체의 메서드가 final/static인 경우 이를 가로채지 않습니다. 즉, 프록시 개체의 추가 비즈니스 메서드가 실행되지 않습니다.

「2. 적용 예:」

  • 首先要添加cglib相关依赖:

<code><dependency><br>     <groupId>cglib</groupId><br>     <artifactId>cglib</artifactId><br>     <version>3.3.0</version><br></dependency><br></code>
 
  • TeacherDaoImpl.java:

<code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
 
  • CglibProxyFactory.java:

<code>// 需要实现MethodInterceptor并重写其方法<br>public class CglibProxyFactory implements MethodInterceptor {<br><br>    private Object target;<br><br>    public CglibProxyFactory(Object target){<br>        this.target = target;<br>    }<br><br>    /**<br>     * 返回target的代理对象<br>     * @return<br>     */<br>    public Object getProxyInstance(){<br>        // 1. 创建工具类<br>        Enhancer enhancer = new Enhancer();<br>        // 2. 设置父类<br>        enhancer.setSuperclass(target.getClass());<br>        // 3. 设置回调函数<br>        enhancer.setCallback(this);<br>        // 4. 创建子类对象,即代理对象<br>        return enhancer.create();<br>    }<br>    @Override<br>    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {<br>        System.out.println("CGLIB代理开始");<br>        Object returnValue = method.invoke(target, args);<br>        System.out.println("CGLIB代理结束");<br>        return returnValue;<br>    }<br>}<br></code>
 
  • Client.java:通过代理调用方法

<code>public class Client {<br><br>    public static void main(String[] args){<br>        // 创建被代理的对象<br>        TeacherDaoImpl target = new TeacherDaoImpl();<br>        // 获取代理对象,并将被代理对象传给代理对象<br>        TeacherDaoImpl proxy = (TeacherDaoImpl) new CglibProxyFactory(target).getProxyInstance();<br>        // 执行方法,触发intecept方法,从而实现执行被代理对象的方法<br>        proxy.teach();<br>    }<br>}<br></code>

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

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제