常用java代理方法

本文深入探讨了Java代理模式中的两种主要实现方式:JDK动态代理和CGLIB代理。不仅详细解析了这两种代理的工作原理,还提供了丰富的示例代码帮助读者理解如何在实际开发中运用这些技术。

1、jdk proxy

jdk proxy是java自带的,不需要依赖其他第三方jar包。但是它只能对接口做代理。
示例代码:
class ServiceProxy implements InvocationHandler {
        /** proxy target service */
        private Object target;
        /**
         * constructor
         * 
         * @param target service to proxy 
         */
        public ServiceProxy(Object target) {
            this.target = target;
        }
        /** 
         * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return method.invoke(target, args);
        }
    }
    InvocationHandler invocationHandler = new ServiceProxy(target);
    ClassLoader       classLoader       = ServiceProxy.class.getClassLoader();
    return Proxy.newProxyInstance( classLoader, target.getClass().getInterfaces(), ih );

2、CGLIB
cglib主要包含4个概念,BeanGenerator、Enhancer、MethodInterceptor、LazyLoader、Dispatcher。
1)BeanGenerator:
beangenerator主要用于动态生成一个类的子类,可以给子类动态添加一些成员变量,自动生成Getter、Setter方法。缺点是它只能生成含默认构造函数的子类。

    BeanGenerator gen = BeanGenerator();
    gen.setSuperclass(SuperClass.class);
    gen.addProperty("name", String.class);
    Class subClazz = (Class)gen.createClass();
    SuperClass obj = (SuperClass)gen.create();

2)Enhancer:
enhancer用于实现某个方法调用的aop功能。enhancer生成对象会包含很多cglib自动添加进去的属性,所以最后生成的对象会比较大。

3)MethodInterceptor:

public class MethodInterceptorImpl implements MethodInterceptor{
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                return proxy.invokeSuper(obj, args);
        }
    }
    //代理invoke方法
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(clazz);
    enhancer.setCallbacks(new Callback[]{NoOp.INSTANCE, new MethodInterceptorImpl()});
    enhancer.setCallbackFilter(new CallbackFilter() {
        @Override
        public int accept(Method method) {
            //只拦截Algorithm接口定义的invoke方法
            if(method.getName().equals("invoke"))
                return 1;
            return 0;
        }
    });
    enhancer.setUseFactory(false);
    //new 出对象
    Object proxy = enhancer.create();
4)LazyLoader:
lazyLoader是cglib的代理延迟初始化接口。当接口方法被第一次调用时,才确定实际要访问的对象。
    public class ConcreteClassLazyLoader implements LazyLoader{
        public class PropertyBean {
            private String propertyName;  
            public String getPropertyName() {
                return propertyName;
            }
            public void setPropertyName(String propertyName) {
                this.propertyName = propertyName;
            }
        }
        @Override
        public Object loadObject() throws Exception {  
            System.out.println("LazyLoader loadObject() ...");  
            PropertyBean bean=new PropertyBean();  
            bean.setPropertyName("lazy-load object propertyName!");  
            return bean;  
        }
        public static void main(String[] args){
            Enhancer enhancer=new Enhancer();  
            enhancer.setSuperclass(PropertyBean.class);  
            PropertyBean propertyBean = (PropertyBean)enhancer.create(PropertyBean.class,
new ConcreteClassLazyLoader());  
            //此处会回调loadObject
            System.out.println(propertyBean.getPropertyName());
            System.out.println("after...");  
            //之后不再回调loadObejct,直接访问第一次返回的对象 
            System.out.println(propertyBean.getPropertyName());  
        }
    }
5)Dispatcher:
Dispatcher功能与LazyLoader相同,只是dispatcher每次都会被回调。
    public class ConcreteDispatcher implements Dispatcher{
        public class PropertyBean {
            private String propertyName;  
            public String getPropertyName() {
                return propertyName;
            }
            public void setPropertyName(String propertyName) {
                this.propertyName = propertyName;
            }
        }
        @Override
        public Object loadObject() throws Exception {  
            System.out.println("Dispatcher loadObject() ...");  
            PropertyBean bean=new PropertyBean();  
            bean.setPropertyName("Dispatcher object propertyName!");  
            return bean;  
        }
        public static void main(String[] args){
            Enhancer enhancer=new Enhancer();  
            enhancer.setSuperclass(PropertyBean.class);  
            PropertyBean propertyBean = (PropertyBean)enhancer.create(PropertyBean.class,new ConcreteDispatcher());  
            //此处会回调loadObject
            System.out.println(propertyBean.getPropertyName());
            System.out.println("after...");  
            //每次都回调loadObejct
            System.out.println(propertyBean.getPropertyName());  
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值