静态与动态代理
在我们了解反射之前,我们使用的是静态代理,会有代理类与被代理类同时实现一个接口,以达到通过调代理类来调用被代理类的一些方法
一.静态代理
interface ClothFac{ void productCloth();}//代理类class proClothFac implements ClothFac{ private ClothFac clothFac; public proClothFac(ClothFac clothFac){ this.clothFac = clothFac; } public proClothFac() { } @Override public void productCloth() { System.out.println("准备开始"); clothFac.productCloth(); System.out.println("结束"); }}//被代理类class Nike implements ClothFac{ @Override public void productCloth() { System.out.println("nike生产鞋子"); }}public class Text2{ public static void main(String[] args) { //创建被代理类对象 Nike nike = new Nike(); //创建代理类对象 proClothFac proClothFac = new proClothFac(nike); proClothFac.productCloth(); }}
二.动态代理(发射)
-
先介绍如何通过反射调用方法
import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class preTest{ public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { //创建运行时类对象 Class personClass = Person.class; //获取方法 Method maoo = personClass.getDeclaredMethod("maoo", String.class); //确保当前方法可访问 maoo.setAccessible(true); //返回值为该方法的返回值,若为void,返回null Object abc = maoo.invoke(personClass, "abc"); System.out.println(abc); }}
2.动态代理
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;interface Human{ String getBelief(); void eat(String food);}class SuerMan implements Human{ @Override public String getBelief() { return "I have a dream"; } @Override public void eat(String food) { System.out.println("我喜欢吃" + food); }}class ProxyfACTORY{ //该方法是动态返回一个代理类对象 public static Object getPro(Object obj)//这里的obj是被代理类{ My my = new My(); my.bind(obj); //这里我们分别让代理类与被代理类实现一样的接口与类的加载器 //当调用此方法时,会自动调用My里面的方法 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),my); }}//实现接口达到通过调用代理类的方法,动态的去调用被代理类同名的方法class My implements InvocationHandler{ private Object obj; public void bind(Object obj){ this.obj = obj;//得到被代理类对象 } @Override //但我们调用代理类的对象的一个方法时,会调用如下的方法,因为前面将该类的对象放入了newProxyInstance中 //将被代理类要执行的方法声明在invoke中 //proxy代理类对象,method方法,args方法形参 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //利用反射调用方法 Object invoke = method.invoke(obj, args); return invoke; }}public class yyy { public static void main(String[] args) { SuerMan suerMan = new SuerMan(); Human pro = (Human) ProxyfACTORY.getPro(suerMan); pro.eat("海鲜"); String belief = pro.getBelief(); System.out.println(belief); }}