动态代理-增强方法

本文介绍了如何使用Java动态代理模式来实现方法的增强。在传统的装饰者模式中,当被增强的类实现多个接口时,需要重写所有接口方法。而动态代理则允许我们只增强特定的方法。通过Proxy类的newProxyInstance方法,结合InvocationHandler接口,可以在运行时创建代理对象并控制方法的执行,实现灵活的增强逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法的增强

  *继承:能够控制这个类

  *装饰者:增强的类和被增强的类实现相同的接口,增强的类中获得到被增强的类的引用.

  接口中方法过多,只增强其中的某个方法.其他的方法也需要重写.

  *动态代理:被增强的类实现了接口.

代理的概述

代理:
JDK中动态代理	:Proxy对象.
* Proxy.newProxyInstance(ClassLoader cl,Class[] interfaces,InvocationHandler ih);

    在使用装饰着模式去增强某个类的时候会发现当被增强的那个类所实现的接口中含有的方法有很多个时,我们就需要将全部的方法都进行重写,显然这是不符合开发的习惯的,那有没有一种方式可以之增强我们需要的那个方法呢,下面还是以案例的形式来进行分析。

    我们首先需要对Proxy有一定了解:

1、 Proxy是位于java.lang.reflect下的类;

2、  Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

3、使用此简便方法来实现接口Foo代理:Foo f = (Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(),

                                                                  newClass[] { Foo.class },

                                                                  handler);

如果想对动态代理有更多的了解请查看jdkAPI文档。

利用动态代理模式来增强方法


在使用装饰着模式去增强某个类的时候会发现当被增强的那个类所实现的接口中含有的方法有很多个时,我们就需要将全部的方法都进行重写,显然这是不符合开发的习惯的,那有没有一种方式可以之增强我们需要的那个方法呢,下面还是以案例的形式来进行分析。

我们首先需要对Proxy有一定了解:

1、 Proxy是位于java.lang.reflect下的类;

2、  Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

3、使用此简便方法来实现接口Foo代理:Foo f = (Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(),

                                                                  newClass[] { Foo.class },

                                                                  handler);

如果想对动态代理有更多的了解请查看jdkAPI文档。

代码如下:

接口类:Waiter

  1. public interface Waiter {  
  2.     public void serve();  
  3.     public String sayhello();  
  4. }  
public interface Waiter {
	public void serve();
	public String sayhello();
}

实现类:Waitress

  1. public class Waitress implements Waiter {  
  2.   
  3.     @Override  
  4.     public void serve() {  
  5.         System.out.println("您要点儿什么呢?");  
  6.     }  
  7.     @Override  
  8.     public String sayhello() {  
  9.         System.out.println("hello world");  
  10.         return null;  
  11.     }  
  12.   
  13. }  
public class Waitress implements Waiter {

	@Override
	public void serve() {
		System.out.println("您要点儿什么呢?");
	}
	@Override
	public String sayhello() {
		System.out.println("hello world");
		return null;
	}

}

代理类:ProxyDemo

  1. import java.lang.reflect.InvocationHandler;  
  2. import java.lang.reflect.Method;  
  3. import java.lang.reflect.Proxy;  
  4.   
  5. import org.junit.Test;  
  6.   
  7. public class ProxyDemo {  
  8.     @Test  
  9.     public void strengthen(){  
  10.         //获得要增强实现类的对象  
  11.         final Waiter waiter = new Waitress();  
  12.         /* 
  13.          * Proxy为代理类。 
  14.          * newProxyInstance为Proxy的静态方法,此方法用于实现动态代理 
  15.          * 返回值为增强类要实现的接口对象 
  16.          * 此方法需要接受三个参数:类加载器、被增强类所要实现的全部接口、处理类 
  17.          *  
  18.          */  
  19.         //类加载器  
  20.         ClassLoader classLoader = waiter.getClass().getClassLoader();  
  21.         //被增强类所要实现的全部接口  
  22.         Class<?>[] interfaces = waiter.getClass().getInterfaces();  
  23.         //处理类一般是通过创建匿名内部类来实现的。  
  24.         Waiter waiterProxy = (Waiter)Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {  
  25.             /* 
  26.              * proxy:产生的代理对象的引用 
  27.              * method:当前正在调用的目标类的方法 
  28.              * params:只在执行的方法中的参数。 
  29.              */  
  30.             //需要注意的是我们无论调用waiterProxy中的任何方法都会执行invoke。所以我们可以在invoke中做一个判断,  
  31.             //从而只执行我们想要的方法。  
  32.             @Override  
  33.             public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {  
  34.                 //根据方法名来执行我们需求中的方法。  
  35.                 if("serve".equals(method.getName())){  
  36.                     System.out.println("欢迎光临");  
  37.                     //这里我们使用了method的invoke来执行waiterProxy中的方法。  
  38.                     Object object = method.invoke(waiter, params);  
  39.                     System.out.println("谢谢光临");  
  40.                     return object;  
  41.                 }else{  
  42.                     //只执行了原来的方法,没有进行增强。  
  43.                     Object object = method.invoke(waiter, params);   
  44.                     return object;  
  45.                 }  
  46.                   
  47.             }  
  48.         });  
  49.         waiterProxy.serve();  
  50.         //waiterProxy.sayhello();  
  51.     }  
  52. }  
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.junit.Test;

public class ProxyDemo {
	@Test
	public void strengthen(){
		//获得要增强实现类的对象
		final Waiter waiter = new Waitress();
		/*
		 * Proxy为代理类。
		 * newProxyInstance为Proxy的静态方法,此方法用于实现动态代理
		 * 返回值为增强类要实现的接口对象
		 * 此方法需要接受三个参数:类加载器、被增强类所要实现的全部接口、处理类
		 * 
		 */
		//类加载器
		ClassLoader classLoader = waiter.getClass().getClassLoader();
		//被增强类所要实现的全部接口
		Class<?>[] interfaces = waiter.getClass().getInterfaces();
		//处理类一般是通过创建匿名内部类来实现的。
		Waiter waiterProxy = (Waiter)Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
			/*
			 * proxy:产生的代理对象的引用
			 * method:当前正在调用的目标类的方法
			 * params:只在执行的方法中的参数。
			 */
			//需要注意的是我们无论调用waiterProxy中的任何方法都会执行invoke。所以我们可以在invoke中做一个判断,
			//从而只执行我们想要的方法。
			@Override
			public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
				//根据方法名来执行我们需求中的方法。
				if("serve".equals(method.getName())){
					System.out.println("欢迎光临");
					//这里我们使用了method的invoke来执行waiterProxy中的方法。
					Object object = method.invoke(waiter, params);
					System.out.println("谢谢光临");
					return object;
				}else{
					//只执行了原来的方法,没有进行增强。
					Object object = method.invoke(waiter, params); 
					return object;
				}
				
			}
		});
		waiterProxy.serve();
		//waiterProxy.sayhello();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值