java 动态代理

代理

通过不直接访问被代理对象的方式,而访问被代理对象的方法,这样的模式称为代理。

应用场景

  1. 在不修改源码的情况下,增强一些方法,在方法执行前后做任何你想做的事情;
  2. 在使用RPC框架的时候,可以通过动态代理的方式来进行逻辑搭建,实现松耦合;
  3. SpringAOP 便是采用的动态代理的机制来完成的。

开闭原则

所谓开闭原则就是:对修改关闭,对扩展开放。java的动态代理便是基于这个原则之上的。

静态代理

在编译时就已经将接口,被代理类,代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成,这种代理称为静态代理。

代码示例

/**
 * 顶层接口
 * 游戏玩家
 * @author smlf
 *
 */
public interface Player {
	void win();
}
/**
 * 需要被代理的类
 * 红方玩家
 * @author smlf
 *
 */
public class RedTeamPlayer implements Player {
	@Override
	public void win() {
		System.out.println("I Win");
	}
}
/**
 * 静态代理类
 * @author smlf
 *
 */
public class ProxyRedTeamPlayer implements Player {
	
	private RedTeamPlayer redTeamPlayer;

	public ProxyRedTeamPlayer(RedTeamPlayer redTeamPlayer) {
		this.redTeamPlayer = redTeamPlayer;
	}
	
	@Override
	public void win() {
		System.out.println("I'm ProxyRedTeamPlayer");
		redTeamPlayer.win();
	}

	public RedTeamPlayer getRedTeamPlayer() {
		return redTeamPlayer;
	}

	public void setRedTeamPlayer(RedTeamPlayer redTeamPlayer) {
		this.redTeamPlayer = redTeamPlayer;
	}
}
public class StaticProxyTest {

	public static void main(String[] args) {
		//redPlayer为被代理的对象,某些情况下 我们不希望修改已有的代码,我们采用代理来间接访问
		RedTeamPlayer redPlayer = new RedTeamPlayer();
		//创建代理类对象
		ProxyRedTeamPlayer player = new ProxyRedTeamPlayer(redPlayer);
		//调用代理类对象的方法
		player.win();
	}

}

输出结果
在这里插入图片描述

总的说来,静态代理是在代理类中引入了被代理类的对象,对原对象的方法进行了增强。

动态代理

在开发时不能确定代理类和被代理类,那么可以使用类的动态加载机制,在代码运行期间加载被代理的类这就是动态代理,比如RPC框架和Spring AOP机制。

java.lang.reflect 包下提供了 Proxy 类和 InvocationHandler 接口,通过这个类和接口可以生成java动态代理类和动态代理对象。

Proxy提供了用于创建动态代理类和代理对象的静态方法:

  1. static Class<?> getProxyClass(ClassLoader loader, Class<?>… interfaces):创建一个动态代理类所对应的 Class 对象(即动态生成一个类),该代理类将实现interfaces所指定的所有接口;
  2. static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h): 创建一个动态代理对象,该代理对象的实现类实现了interfaces对应的所有接口,执行代理对象的每个方法时会被替换成执行InvocationHandler对象(h)的invoke方法。

事实上,采用第一种方式生成动态代理类以后,如果需要创建该代理类对应的对象,依然需要传入一个InvocationHandler对象。

代码示例

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class PlayerInvocationHandler implements InvocationHandler{

	@Override
	public Object invoke(Object object, Method method, Object[] params) throws Throwable {
		System.out.println("I'm dynamicProxy Player");
		return null;
	}
	
}
public class DynamicProxyTest {
	
	public static void main(String[] args) {
		// 创建被代理类的委托类,之后想要调用被代理类的方法时,都会委托给这个类的invoke(Object object, Method method, Object[] params)方法
		PlayerInvocationHandler h = new PlayerInvocationHandler();
		//生成代理类
		Player proxy = (Player)Proxy.newProxyInstance(Player.class.getClassLoader(), new Class[] {Player.class}, h);
		proxy.win();
	}

}

执行结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值