java 동적 에이전트와 cglib 동적 에이전트 예시 공유

java 동적 에이전트 클래스는 두 가지로 나눌 수 있습니다.정적 에이전트: 프로그래머가 만들거나 특정 도구가 자동으로 원본 코드를 생성하고 컴파일합니다.프로그램이 실행되기 전에 프록시 종류의.class 파일이 이미 존재합니다.동적 에이전트: 프로그램이 실행될 때 반사 메커니즘을 활용하여 동적으로 만듭니다.1. 우선 자바 동적 에이전트의 프레젠테이션을 진행합니다.
현재 우리는 간단한 업무 인터페이스 Saying을 가지고 있다. 다음과 같다.

package testAOP;
public interface Saying {
public void sayHello(String name);   
public void talking(String name);
}
간단한 구현 클래스 SayingImpl:

package testAOP;
public class SayingImpl implements Saying {
    @Override
    public void sayHello(String name) {
        // TODO Auto-generated method stub
        System.out.println(name + ": !");
    }
    @Override
    public void talking(String name) {
        // TODO Auto-generated method stub
        System.out.println(name + ": , !");
    }
}
우리가 실현하고자 하는 것은sayHello와talking 전과 후에 각각 동적 식입 처리를 하는 것이다.
JDK 동적 에이전트는 주로java에 사용됩니다.lang.reflect 패키지의 두 종류: Proxy와 InvocationHandler.
InvocationHandler는 인터페이스로 이 인터페이스를 통해 횡단 논리를 정의하고 반사 메커니즘을 통해 목표 클래스의 코드를 호출하여 동적으로 횡단 논리와 업무 논리를 한데 엮는다.
Proxy는 InvocationHandler를 이용하여 어떤 인터페이스에 맞는 실례를 동적으로 만들고 목표 클래스의 프록시 대상을 생성합니다.
다음과 같이 InvocationHandler 인스턴스를 만듭니다.

package testAOP;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {

    private Object target;
    MyInvocationHandler(Object target){
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //
        System.out.println("――――――――――――――――――――――――――");
        System.out.println(" !");
        //
        Object obj = method.invoke(target, args);
        //
        System.out.println(" !");
        return obj;
    }
}

다음은 테스트입니다.

package testAOP;
import java.lang.reflect.Proxy;
public class JDKProxyTest {

    public static void main(String[] args) {
        //
        Saying target = new SayingImpl();
        //
        MyInvocationHandler handler = new MyInvocationHandler(target);
        //
        Saying proxy = (Saying) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),//
                target.getClass().getInterfaces(),//
                handler);//
        proxy.sayHello(" ");
        proxy.talking(" ");
    }
}
운영 상황은 다음과 같습니다.

――――――――――――――――――――――――――

: !

――――――――――――――――――――――――――

: , !

JDK 동적 에이전트를 사용하는 데는 큰 제한이 있다. 바로 목표 클래스가 대응하는 방법의 인터페이스를 실현해야 한다는 것이다. 이것은 인터페이스를 위한 에이전트 실례만 만들 수 있다.우리는 상기 테스트 클래스 중의 Proxy의 new Proxy Instance 방법에서 볼 수 있듯이 이 방법의 두 번째 매개 변수는 바로 목표 클래스의 인터페이스이다.만약 이 종류가 인터페이스를 실현하지 못한다면, 이것은 cglib 동적 에이전트에 의존해야 한다.
CGLib는 매우 밑바닥의 바이트 코드 기술을 사용하여 하나의 클래스에 하나의 하위 클래스를 만들고 하위 클래스에서 방법으로 차단하는 기술로 모든 부류 방법의 호출을 차단하며 흐름에 따라 횡단 논리를 심어 넣을 수 있다.
둘째, 다음에 우리는 cglib 동적 에이전트의 시범을 진행한다.
우선 가이드가 필요합니다. 제가 쓰는 가방은 cglib-nodep-2.1_3.jar.
프록시 생성기 CglibProxy를 먼저 만듭니다.

package testAOP.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor{

    Enhancer enhancer = new Enhancer();
    public Object getProxy(Class clazz) {
        //
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        //
        return enhancer.create();
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("――――――――――――――――――――――――――");
        System.out.println(" !");
        //
        Object result = proxy.invokeSuper(obj, args);
        //
        System.out.println(" !");
        return result;
    }   
}

그리고 테스트를 진행합니다.

package testAOP.cglib;
import testAOP.Saying;
import testAOP.SayingImpl;
public class CglibProxyTest {

    public static void main(String[] args) {
        CglibProxy proxy = new CglibProxy();
        //
        Saying target = (Saying) proxy.getProxy(SayingImpl.class);
        target.sayHello(" ");
        target.talking(" ");
    }
}

결과는 JDK 동적 에이전트와 다를 바 없습니다.
JDK 동적 에이전트와 CGLib 동적 에이전트는 모두 실행할 때 강화되며, 가로 코드를 에이전트 클래스에 삽입하는 방식으로 강화됩니다.이와 달리 AspectJ는 특수한 컴파일러를 통해 컴파일할 때 횡단 코드를 증강에 삽입할 수 있다. 이런 증강 처리는 실행할 때 더욱 유리하다. 왜냐하면 JDK 동적 에이전트와 CGLib 동적 에이전트는 실행할 때마다 증강이 필요하기 때문이다.

좋은 웹페이지 즐겨찾기