栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java动态代理使用小记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java动态代理使用小记

代理的优点

代理是一种很重要的思想,了解代理的使用对我们的coding很有帮助。使用代理的一些优点:

  • 可以做共性的逻辑处理,比如鉴权、日志、事务等等,实际上这也是AOP的作用
  • 屏蔽网络差异和复杂性,代理在本地,而实际对象(服务)在其他服务器上,调用本地代理时,由本地代理请求其他服务器(如Dubbo的网络调用)
动态代理的方式 1.JDK动态代理

创建方式:

public interface IServiceFoo {
    void sayHello();
}

public class ServiceFooImpl implements IServiceFoo {

    @Override
    public void sayHello() {
        System.out.println("action: ServiceFooImpl.sayHello");
    }
}


public class SimpleInvocationHandler implements InvocationHandler {

	//被代理的真正的目标对象
    private Object realObj;

    public SimpleInvocationHandler(Object realObj) {
        this.realObj = realObj;
    }

    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("entering " + method.getDeclaringClass().getSimpleName() + ":: " + method.getName());
        Object result = method.invoke(this.realObj, args);
        System.out.println("leaving " + method.getDeclaringClass().getSimpleName()+":: " + method.getName());

        return result;
    }
}

public class TestA {

    public static void main(String[] args) {
        IServiceFoo realService = new ServiceFooImpl();
        IServiceFoo proxyInstance = getProxy(IServiceFoo.class, realService);
        proxyInstance.sayHello();
    }

    
    private static  T getProxy(Class targetInterface, T realObject) {
        return (T) Proxy.newProxyInstance(targetInterface.getClassLoader(),//类加载器
                new Class[] {targetInterface},//被代理的接口数组
                new SimpleInvocationHandler(realObject));//调用处理器
    }
}

JDK动态代理就是使用Java的反射包java.lang.reflect提供的相关API去实现即可:
Proxy/InvocationHandler

1.cglib动态代理

jdk动态代理的局限在于,它只能为接口创建代理,返回的代理对象也只能转换到某个接口类型,如果要代理类,我们需要使用cglib动态代理。创建方式如下:

public class DemoTest {

    static class FooService {
        public final void testMethod() {
            System.out.println("FooService.testMethod action");
        }
    }

    
    static class SimpleInterceptor implements MethodInterceptor {

        
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println("entering " + method.getDeclaringClass().getSimpleName() + "::" + method.getName());
            //调用超类的方法:即调用被代理的类的方法
            Object result = methodProxy.invokeSuper(proxy, args);
            System.out.println("leaving " + method.getDeclaringClass().getSimpleName() + "::" + method.getName());
            return result;
        }
    }

    
    private static  T getProxy(Class targetClass) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(targetClass);
        enhancer.setCallback(new SimpleInterceptor());
        enhancer.setUseCache(true);
        return (T) enhancer.create();
    }

    public static void main(String[] args) {
        FooService proxy = getProxy(FooService.class);
        proxy.testMethod();
    }
}

cglib的实现机制与java不同,它是通过继承实现的,它也是动态创建了一个类,
但这个类的父类是被代理的类,代理类重写了父类的所有public非final方法,
并且目标类方法的调用改为调用Callback中的相关方法,如上述code,调用SimpleInterceptor的intercept方法。

cglib动态代理注意事项,被代理类中定义的final方法可以被调用但是不会走代理逻辑,因为final方法无法被子类(代理类)重写

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/856709.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号