Java实现动态代理(cglib、jdk)

1.适用场景(基于cglib实现的动态代理):

       当我们需要给没有实现接口的目标类生成代理对象时,jdk的动态代理就完成不了这样的事情了,这时我们就可以继承目标类,以目标类的子类方式实现,这样的方法叫做cglib的动态代理,也可以叫做子类代理,它是在内存中构建一个子类对象从而对目标对象进行功能的增强。

2.上代码:

/**
 * cglib动态代理原方法
 * @author xpzhang
 *
 */
public class Refund {
    public void refund() {
        System.out.println("我是退款原逻辑");
    }
}

/**
 * 基于cglib实现的动态代理
 * @author xpzhang
 *
 */
public class CglibProxyFactory implements MethodInterceptor{
    //维护目标对象
    private Object target;
    
    public CglibProxyFactory(Object target) {
        this.target = target;
    }
    /**
     * 获得目标类的代理对象
     * @return
     */
    public Object getObject() {
        //工具类
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(target.getClass());
        //设置回调
        enhancer.setCallback(this);
        //创建代理类
        Object object = enhancer.create();
        return object;
    }

    @Override
    public Object intercept(Object arg0, Method method, Object[] objects, MethodProxy arg3) throws Throwable {

         
        System.out.println("cglib代理前退款的逻辑");
        //执行目标对象的目标方法
        method.invoke(target,objects);
        
        System.out.println("cglib代理后退款新增逻辑");

        return null;
    }

}

/**
 * cglib测试类
 * @author xpzhang
 *
 */
public class MainTest {
    public static void main(String[] args) {
        
        Refund refund = new Refund();
        Refund proxyObject = (Refund) new CglibProxyFactory(refund).getObject();
        proxyObject.refund();
    }
}

3.基于JDK实现的动态代理,上代码:

/**
 * 交易接口
 * @author PengMvc
 *
 */
public interface Itransfer {
	// 退款
	public void refund();
}


/*
 * 对退款接口进行功能增强,譬如新增核对交易信息
 */
public class RefundImpl implements Itransfer{

	@Override
	public void refund() {
		System.out.println("调用退款接口进行退款了!");
		
	}
}


/**
 * 基于jdk的动态代理
 * @author PengMvc
 *
 */
public class RefundProxy implements InvocationHandler{
	
	// 目标对象
	private Object target;
	
	public void setTarget(Object target) {
		this.target=target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object result = method.invoke(target, args);
		// 这里添加增强的功能
		System.out.println("<基于JDK进行功能增强>:退完款了,准备调用交易明细接口进行核对了!");
		return result;
	}
	// 获取代理对象
	public Object getProxyInstance() {
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}
}


/**
 * 测试类
 * @author PengMvc
 *
 */
public class TestDynamicProxy {
	public static void main(String[] args) {
		RefundProxy refundProxy = new RefundProxy();
		refundProxy.setTarget(new RefundImpl());
		Object proxyInstance = refundProxy.getProxyInstance();
		((Itransfer) proxyInstance).refund();;
	}
}

4.基于jdk的动态代理实现:

/**
 * 退款的表现层入口
 * @author PengMvc
 *
 */
public class RefundController {
	
	private  Irefund refund = (Irefund) RefundProxy.getProxyInstance(new RefundImpl());
	
	public Boolean refund() {
		return refund.refund();
	}
	
	public static void main(String[] args) {
		RefundController refundController = new RefundController();
		Boolean flag = refundController.refund();
		String resultMsg = flag ? "退款和清分成功":"退款和清分失败";
		System.out.println(resultMsg);
	}
}

/**
 * 退款接口
 * @author PengMvc
 *
 */
public interface Irefund  {
	
	public Boolean refund();

}

/**
 * 退款接口的具体实现类
 * @author PengMvc
 *
 */
public class RefundImpl implements Irefund{

	@Override
	public Boolean refund() {
		System.out.println("这里是具体的退款业务逻辑");
		return true;
	}

}

/**
 * 这是一个通用的接口
 * 通过动态代理对现有功能进行增强
 * @author PengMvc
 *
 */
public class RefundProxy implements InvocationHandler {
	
	private static final RefundProxy  commonProxy = new RefundProxy();
	
	private  Iclearing clear = new ClearingImpl();
	
	private Object target;
	
	// 需要增强的类(被代理对象)
	private static void setTarget(Object target) {
		commonProxy.target = target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Boolean ifRefund = (Boolean) method.invoke(target,args);
		
		System.out.println("<退款结束通过动态代理对现有功能进行增强>"+ifRefund);
		Boolean ifClearing = clear.clearing();
		Boolean ifSuccessFlag = (ifClearing && ifRefund) ? true : false;
		return ifSuccessFlag;
	}
	
	public static Object getProxyInstance(Object target) {
		
		if(target == null) {
			throw new InaccessibleObjectException("设置被代理对象出错!");
		}
		setTarget(target);
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), commonProxy);
	}
}

/**
 * 清分接口
 * @author PengMvc
 *
 */
public interface Iclearing {
     public Boolean clearing();
}

/**
 * 清分接口实现类
 * @author PengMvc
 *
 */
public class ClearingImpl implements Iclearing{

	@Override
	public Boolean clearing() {
		System.out.println("这里是清分的具体逻辑");
		return false;
	}

}

5.总结:利用动态代理,可以在不改变业务类逻辑的前提下,对业务类进行功能的增强,在开发中如果有接口的我们可以用jdk的动态代理,若没有接口,我们可以用基于cglib的动态代理、一般情况下,我们很少使用静态代理,因为静态代理对子类的维护成本太高了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值