当前位置:首页 > 分类 > JAVA高级 > JAVA动态代理(jdk代理和cglib代理)

JAVA动态代理(jdk代理和cglib代理)

动态代理在切面编程中大量被使用,即使用目标类生成代理类,用代理类代替目标类完成任务。

jdk代理使用java反射机制实现,拦截接口,为目标类生成实现相同接口的实现类,代理类的创建高效。

cglib代理使用asm(字节码编程)实现,拦截目标类,为目标类生成子类,代理类的执行高效。


首先定义接口和接口实现类,jdk代理必须定义接口

public interface TestInterface extends Cloneable,Serializable{
void a();
default void b(){ System.out.println("youfengxin.com"); }
}

@TestAnnocation
class TestCalss implements TestInterface{
@Override
public void a() {System.out.println("youfengxin.com");}
}


使用的注解

@Retention(RetentionPolicy.RUNTIME)
@Target(value={TYPE})
public @interface TestAnnocation {

}


jdk代理

public class TestJdkInvocation implements InvocationHandler{

private Object object;

public TestJdkInvocation(Object object){this.object = object;}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   System.out.println("do something before " + method.getName());
           Object result = method.invoke(object, args);
           System.out.println("do something after " + method.getName());
           return result;
}

//test
public static void main(String[] args) throws Exception {
String classParam = "com.youfengxin.TestCalss";
String methodParam = "a";
Class<?> clazz = Class.forName(classParam);
if(clazz.isAnnotationPresent(TestAnnocation.class)){
TestJdkInvocation testJdkInvocation = new TestJdkInvocation(clazz.newInstance());
Object testInterfaceProxy =Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(), testJdkInvocation);
//test
testInterfaceProxy.getClass().getDeclaredMethod(methodParam).invoke(testInterfaceProxy);
}
}
}

实现InvocationHandler接口,重写invoke方法,Proxy.newProxyInstance生成代理类。


cglib代理

public class TestCglibInvocation implements MethodInterceptor{

@Override
public Object intercept(Object obj, Method method, Object[] param, MethodProxy methodProxy) throws Throwable {
System.out.println("do something before " + method.getName());
Object result = methodProxy.invokeSuper(obj, param);
System.out.println("do something after " + method.getName());
return result;
}
public static void main(String[] args) throws Exception {
String classParam = "com.youfengxin.TestCalss";
String methodParam = "a";
Class<?> clazz = Class.forName(classParam);
TestCglibInvocation cglibProxy = new TestCglibInvocation();
               Enhancer enhancer = new Enhancer();
               enhancer.setSuperclass(clazz);
               enhancer.setCallback(cglibProxy);
               Object object = enhancer.create();
               object.getClass().getDeclaredMethod(methodParam).invoke(object);

}
}

需导入cglib.jar和asm.jar

实现MethodInterceptor接口,重写intercept方法,enhancer.create()生成增强类。