java静态代理与动态代理实例
静态代理
package learnReflect3;
/**
* 静态代理
* 特点: 代理类和被代理类在编译期间,就确定下来了
*/
interface ClothFactory{
void produceCloth();
}
// 代理类
class ProxyClothFactory implements ClothFactory{
private ClothFactory factory; // 用被代理类对象进行实例化
public ProxyClothFactory (ClothFactory factory){
this.factory = factory;
}
@Override
public void produceCloth() {
System.out.println("代理工厂做一些准备工作");
factory.produceCloth();
System.out.println("代理工厂做一些后续的收尾工作");
}
}
// 被代理类
class NikeClothFactory implements ClothFactory{
@Override
public void produceCloth() {
System.out.println("Nick工厂生产一批运动衣服");
}
}
public class StaticProxyTest {
public static void main(String[] args) {
// 创建被代理对象
NikeClothFactory nick = new NikeClothFactory();
ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nick);
proxyClothFactory.produceCloth();
}
}
动态代理
package learnReflect3;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理
*/
interface Human {
String getBelief();
void eat(String food);
}
// 被代理类
class SuperMan implements Human {
@Override
public String getBelief() {
return "I believe I can fly !";
}
@Override
public void eat(String food) {
System.out.println("我喜欢吃: " + food);
}
}
/*
要想实现动态代理,需要解决的问题?
问题一: 如何根据加载到内存中的被代理类,动态创建一个代理类及其对象
问题二: 通过代理类的对象调用方法时,如何动态的取调用被代理类中的同名方法。
*/
class ProxyFactory {
// 调用此方法,返回一个代理类的对象,解决问题
public static Object getProxyInstance(Object obj) { // obj: 被代理的对象
MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
myInvocationHandler.bing(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), myInvocationHandler);
}
}
class MyInvocationHandler implements InvocationHandler {
private Object obj;// 需要使用被代理类的都西昂进行赋值
public void bing(Object obj) {
this.obj = obj;
}
// 当我们通过代理类的对象,调用方法a时,就会自动的调用如下的方法:invoke()
// 将被代理类要执行的方法a的功能就声明在invoke中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// method: 即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法。
// obj: 被代理类的对象
Object invoke = method.invoke(obj, args);
// 上述方法的返回值,就作为当前类中的invoke()的返回值。
return invoke;
}
}
public class ProxyTest {
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
// proxyInstance: 代理类的对象
Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
// 当执行代理类对象掉哦那个方法时,会自动调用被代理类中同名方法的执行
String belief = proxyInstance.getBelief();
System.out.println(belief); // I believe I can fly !
proxyInstance.eat("火锅"); // 我喜欢吃: 火锅
System.out.println("************动态代理,代理之前写的静态代理*******************");
// 将之前静态代理里的被代理对象用动态代理来代理
NikeClothFactory nikeClothFactory = new NikeClothFactory();
ClothFactory proxyInstance1 = (ClothFactory) ProxyFactory.getProxyInstance(nikeClothFactory);
proxyInstance1.produceCloth(); // Nick工厂生产一批运动衣服
}
}