在我们了解反射之前,我们使用的是静态代理,会有代理类与被代理类同时实现一个接口,以达到通过调代理类来调用被代理类的一些方法
一.静态代理
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);
}
}