一、什么叫jdk的代理?
用另外一个对象去代理实际对象的操作
分为动态代理和静态代理
二、先说说静态代理
从字面意思来看就是不会改变的,只可以代理某个固定对象的。
静态代理就是通过实现和目标对象实现的同一个接口来代理目标对象。
通俗一点:例如A类实现了B接口,这时候我们要代理A类,我们需要声明一个C类也实现B接口,从而达到代理A类的目的;这个时候我们操作A类的方法时,可以通过操作C类来实现。
看代码:
1、写一个接口
public interface MyTest02 { void test01(String a); }
2、写一个类实现这个接口
public class MyTest03 implements MyTest02 { @Override public void test01(String a) { System.out.println(123); } }
3、写一个类来代理
public class MyTest04 implements MyTest02{ private MyTest03 myTest03; public MyTest04(MyTest03 myTest03){ this.myTest03=myTest03; } @Override public void test01(String a) { System.out.println("处理前"); myTest03.test01(a); System.out.println("处理后"); } }
4、编写测试类
public class MainTest { public static void main(String[] args) { MyTest03 myTest03 = new MyTest03(); /* MyTest01 test01 = new MyTest01(myTest03); MyTest02 subject = (MyTest02) Proxy.newProxyInstance(MyTest03.class.getClassLoader(), MyTest03.class.getInterfaces(), test01); subject.test01("456");*/ MyTest04 test04 = new MyTest04(myTest03); test04.test01(""); } }
5、运行结果
6、静态代理总结:
可以在不操作原对象的同时添加前置方法和后置方法,不需要操作原对象的同时更改逻辑,这也是唯一的优点哈,可以说是没有优点!因为需要代理一个类时就需要写一个实现类,一般都是用接下来要说的动态代理!
三、动态代理
静态代理可以实现的功能,动态代理都可以实现!动态代理的实现是在运行时,根据一组接口定义,使用Proxy、InvocationHandler等工具类去生成一个代理类和代理类实例。
相比于静态代理来说,动态代理需要代理一个类的时候不需要额外写一个实现类;大部分的工作都是Proxy工具类帮我们完成的。
看代码:
1、基于上面的代码,写一个类实现InvocationHandler
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyTest01 implements InvocationHandler { private Object subject; /** * 构造方法,给我们要代理的真实对象赋初值 * * @param subject */ public MyTest01(Object subject) { this.subject = subject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //在代理真实对象前我们可以添加一些自己的操作 System.out.println("在调用之前,我要干点啥呢?"); System.out.println("Method:" + method); //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用 Object returnValue = method.invoke(subject, args); //在代理真实对象后我们也可以添加一些自己的操作 System.out.println("在调用之后,我要干点啥呢?"); return returnValue; } }
2、测试类;例如我要代理String这个类从接口CharSequence实现过来的.length()方法
import java.lang.reflect.Proxy;
public class MainTest {
public static void main(String[] args) {
String myTest03 = new String("123");
MyTest01 test01 = new MyTest01(myTest03);
CharSequence subject = (CharSequence) Proxy.newProxyInstance(String.class.getClassLoader(), String.class.getInterfaces(), test01);
System.out.println(subject.length());
}
}
3、运行结果
4、动态代理总结:
要使用jdk的代理功能的话,一般都是使用的动态代理,动态代理和静态代理都需要实现接口才可以进行代理;主要用于添加目标方法逻辑时,又不想改变原代的时候;
如果没有实现接口又想使用代理功能的话,可以去看看cglib动态代理。