动态代理 两种实现方式

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

核心角色:

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

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;
    }

}

你可能感兴趣的:(动态代理 两种实现方式)