初识继承、 组合、动态代理

本文介绍了在Java中如何通过继承、组合以及动态代理三种方式,在不修改原有代码的情况下为方法添加额外的功能。重点讲解了动态代理的实现原理及其优势。

假如我们有一段代码,要在这段代码前加权限,日志,过滤等操作我们该怎么办?我的第一想法就是直接在代码前写代码就好了,可是这样会使业务逻辑的代码量增大,不能使我们专注于业务逻辑的思考,并且如果我们看不到原来的代码就更加无所适从了。

下面通过代码的方式提出三种方法方便大家处理以上情况

首先定义一个接口

public interface Car {
	public void running();
}
其次是他的实现类

public class CarImpl implements Car{

	@Override
	public void running() {
		//System.out.println("start");
		System.out.println("the beautiful girl in the car is crying");
		//System.out.println("end");
	}
}
然后是测试类

public static void main(String[] args) {
		Car car = new CarImpl();
		car.running();
	}
}

 假如我们需要在running前后加些代码,又拿不到CarImpl源码,我们可以采用以下几种方法来解决这个问题 

一:继承

我们可以再写一个实现类CarImpl2继承CarImpl即可,代码如下

public class CarImpl2 extends CarImpl{

	@Override
	public void running() {
		System.out.println("start");
		super.running();
		System.out.println("end");
	}
}

测试类如下

public static void main(String[] args) {
		Car car = new CarImpl2();
		car.running();
	}
这样我们就实现了在前后加代码的功能了,可是这种方法并不好,耦合性太强,父类改了,子类也不得不会做出相应变化,不灵活。并且如果还有别的实现类要增加代码,还得再继承一遍,再写一次代码。

二 :组合

相较于继承,组合具有更大的灵活性,代码如下

这里CarImpl2实现Car接口

public class CarImpl2 implements Car{
	/*
	 * 相当于
	 * private Car car = new CarImpl();
	 **/
	private Car car;
	public CarImpl2(Car car){
		this.car = car;
	}

	@Override
	public void running() {
		System.out.println("start");
		car.running();
		System.out.println("end");
	}
}

测试类如下:

public static void main(String[] args) {
		Car car = new CarImpl2(new CarImpl());
		car.running();
	}
这种写法在代理模式里属于静态代理,他只能为一个类服务,仍有不方便,如果我要是想在每一个类每一个方法前都要加上一段代码,或者说有的要加有的不加,这样我们就不是很方便,如果我们能把这些东西单独拿出来,写在一个xml文件里想必是极好的,这就是 spring的AOP机制,当然今天我们不聊AOP,而是聊AOP背后的原理,动态代理。代理模式分为动态代理和静态代理,代理类对象本身并不真正实现服务,而是通过调用委托类对象的相关方法来提供服务,具体含义大家可以去网上找一下,很多,我不详述。

三:动态代理

如果不深究,动态代理其实就只要记住一个接口一个类即可,即InvovationHandler,Proxy;

这里我们写一个CarProxy类,他继承了InvovationHandler接口,如下;

public class CarProxy implements InvocationHandler {
	private Object target;
	public CarProxy(Object target){
		this.target = target;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("start");
		method.invoke(target, args);
		System.out.println("end");
		return null;
	}

}

测试类如下:

public static void main(String[] args) {
		Car car = new CarImpl();
		CarProxy carProxy = new CarProxy(car);
		Car car1 = (Car)Proxy.newProxyInstance(car.getClass().getClassLoader(), car.getClass().getInterfaces(), carProxy);
		car1.running();
	}



以下两篇大神的文章阐释了Jdk动态代理,贴出来供大家参开

http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html

http://www.cnblogs.com/xiaoluo501395377/p/3383130.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值