Java动态代理回顾

代理:代替某人做一些事情

这里引申出几个属于  委托人、被委托人

通俗说就是 我要找刘德华打广告,我不能直接找上他本人,我要先找他的代理人才行。

为什么不能找上他本人呢?

因为代理可以为他过滤掉一些收益不高或者公司实力不雄厚的广告业务,也就是说代理存在的意义是在真正做某件事前,先做一些事前准备。

Java中有两种代理实现方式 静态代理、动态代理

静态代理:

静态代理实际上就是声明一个和被代理类具有同样方法签名的类,把被代理类实例作为代理类的成员,这样在调用代理类方法,先执行代理类的操作,然后执行被代理类的方法。

被代理类 ,明星能够 拍电影和唱歌

public class Star {
	public void movie() {
		System.out.println("拍电影......");
	}
	
	public void sing() {
		System.out.println("唱歌......");
	}
}

代理类 (StarProxy) 代理明星(Star)承接 拍电影和唱歌的业务

public class StarProxy {
	private Star _star;
	
	public StarProxy(Star star) {
		this._star=star;
	}
	
	public void movie() {
		System.out.println("代理......前");
		_star.movie();
		System.out.println("代理......后");
	}
	
	public void sing() {
		System.out.println("代理......前");
		_star.sing();
		System.out.println("代理......后");
	}
}

在执行代理方法时,在代理方法内部会调用被真正代理类的方法。

public class JMain {

	public static void main(String[] args) {
		StarProxy proxy=new StarProxy(new Star());
		proxy.movie(); //拍电影
		proxy.sing();//唱歌
	}

}

 

动态代理:

动态的为类生成一个代理类,和静态代理最大的不同之处在于,它发生在运行时,不需要单独编写代理类。

在包 java.lang.reflect 下有动态代理的相关实现

这里我们关注两个类型

Proxy和 InvocationHandler

Proxy 根据指定的被代理类class和接口动态生成代理对象

InvocationHandler 代理类实现的接口,当调用被代理类任何方法时,会执行接口Invoke方法。

public static void main(String[] args){
		Star star=new Star();
		
		IStar starproxy=(IStar) Proxy.newProxyInstance(Star.class.getClassLoader(),Star.class.getInterfaces(),new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("代理------前");
				Object ret= method.invoke(star, args);
				System.out.println("代理------后");
				return ret;
			}
		});
		
		starproxy.movie();
		
	}

这里没有预先定义代理类,而是在运行时动态生成的,其底层原理是通过反射来实现,java内置的动态代理 需要被代理类实现一个接口,因此有一定的局限性。

这里介绍另一种实现动态代理的优秀框架 cglib,它采用asm动态织入的方式,在内存中动态生成代理类字节码。

public class JMain {

	public static void main(String[] args) {
		
		StarProxy starProxy = new JMain().new StarProxy();  
		  
        Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(Star.class);  
        enhancer.setCallback(starProxy);  
  
        Star o = (Star)enhancer.create();  
		
		o.movie();
	}

	/***
	 * 定义一个代理类,实现方法拦截器接口
	 * @author RWX
	 *
	 */
	class StarProxy implements MethodInterceptor {
		@Override
		public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			System.out.println("代理调用方法前:" + methodProxy.getSuperName());
			Object o1 = methodProxy.invokeSuper(o, args);
			System.out.println("代理调用方法后: " + methodProxy.getSuperName());
			return o1;
		}
	}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值