美文网首页
动态代理 两种实现方式

动态代理 两种实现方式

作者: 真海ice | 来源:发表于2018-03-12 09:10 被阅读0次

    动态代理(动态生成代理类):可以控制某个对象(类)的方法,可以在调用这个方法前和方法后做些处理。

    核心角色:

    • 抽象角色:定义代理角色和真是角色的对外方法。
    • 真是角色:实现抽象角色,定义真实的角色所要实现的业务逻辑,供代理角色调用;关注真正的业务逻辑。
    • 代理角色:实现抽象的角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并附加自己的操作;将统一的流程控制放到代理角色中处理。

    1. 第一种实现方式:
    Rent:抽象角色,定义动作(租房这个动作)
    Host:真实角色,真实的业务(真正出租的是房东)
    JdkClient:jdk动态代理客户端的调用
    JdkProxyHandler:jdk代理角色,流程控制和附加操作

    package com.test.dynamicProxy;
    
    /**
     * 抽象角色 只定义动作
     * @author zhb
     *
     */
    public interface Rent {
        
        public void seeHouse();
        
        public void signContract();
        
        public void money();
    
    }
    
    
    package com.test.dynamicProxy;
    
    /**
     * 真实角色,真正的业务逻辑
     * @author zhb
     *
     */
    public class Host implements Rent{
    
        @Override
        public void seeHouse() {
            System.out.println("看房");
        }
    
        @Override
        public void signContract() {
            System.out.println("签合同");
        }
    
        @Override
        public void money() {
            System.out.println("付款");
        }   
    
    }
    
    
    package com.test.dynamicProxy.jdk;
    
    import com.test.dynamicProxy.Host;
    import com.test.dynamicProxy.Rent;
    
    /**
     * 调用jdk动态代理类的客户端
     * @author zhb
     *
     */
    public class JdkClient {
        public static void main(String[] args) {
            
            Rent rent = new Host();
            JdkProxyHandler handler = new JdkProxyHandler(rent);
            Rent proxy = (Rent) handler.getProxy();
            proxy.signContract();
        }
    
    }
    
    
    package com.test.dynamicProxy.jdk;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class JdkProxyHandler implements InvocationHandler{
        
        private Object target;
        
        public JdkProxyHandler(Object target){
            this.target = target;
        }
        
        /**
         * 获取动态代理对象
         * @return
         */
        public Object getProxy(){
            return  Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), target.getClass().getInterfaces(), this);
        }
        
        /**
         * 动态执行要方法
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {     
            System.err.println("调用方法"+method.getName()+"前处理");
            method.invoke(target, args);
            System.err.println("调用方法"+method.getName()+"后处理");
            return null;
        }   
    
    }
    
    

    2. 第二种实现方式:
    CglibClient:cglib动态代理客户端的调用
    CglibProxy:cglib代理角色,流程控制和附加操作
    用到的jar包:

    2018-03-12_090936.png
    package com.test.dynamicProxy.cglib;
    
    import com.test.dynamicProxy.Host;
    import com.test.dynamicProxy.Rent;
    
    /**
     * 调用cglib动态代理类的客户端
     * @author zhb
     *
     */
    public class CglibClient {
        
        public static void main(String[] args) {
                    
            CglibProxy cglibProxy = new CglibProxy();
            Rent proxy = (Rent)cglibProxy.getProxy(Host.class);
            
            proxy.signContract();
                    
        }
    
    }
    
    
    package com.test.dynamicProxy.cglib;
    
    import java.lang.reflect.Method;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    /**
     * 
     * @author zhb
     *
     */
    public class CglibProxy implements MethodInterceptor{
            
        /**
         * 获取动态代理对象
         * @param target
         * @return
         */
        public Object getProxy(Object target){
            
            Enhancer enhancer = new Enhancer();  
            enhancer.setSuperclass((Class) target);
            enhancer.setCallback(this);
            return enhancer.create();
        }
        
    
        /**
         * 动态执行要方法
         */
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            
            System.out.println(method.getName());       
            System.err.println("调用方法"+method.getName()+"前处理");
            
            methodProxy.invokeSuper(o, args);
            System.err.println("调用方法"+method.getName()+"后处理");
                    
            return null;
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:动态代理 两种实现方式

          本文链接:https://www.haomeiwen.com/subject/semwfftx.html