方法的增强
*继承:能够控制这个类
*装饰者:增强的类和被增强的类实现相同的接口,增强的类中获得到被增强的类的引用.
接口中方法过多,只增强其中的某个方法.其他的方法也需要重写.
*动态代理:被增强的类实现了接口.
代理的概述
代理:
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
- public interface Waiter {
- public void serve();
- public String sayhello();
- }
public interface Waiter { public void serve(); public String sayhello(); }
实现类:Waitress
- public class Waitress implements Waiter {
- @Override
- public void serve() {
- System.out.println("您要点儿什么呢?");
- }
- @Override
- public String sayhello() {
- System.out.println("hello world");
- return null;
- }
- }
public class Waitress implements Waiter { @Override public void serve() { System.out.println("您要点儿什么呢?"); } @Override public String sayhello() { System.out.println("hello world"); return null; } }
代理类:ProxyDemo
- 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();
- }
- }
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(); } }