反射
1. 静态代理和动态代理
代理设计模式的原理: 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
静态代理。
interface ClothFactory {
void produceCloth();
}
// 代理类
class NikeClothFactory implements ClothFactory {
@Override
public void produceCloth() {
System.out.println("NikeClothFactory");
}
}
// 被代理类
class NikeProxyFactory implements ClothFactory {
private NikeClothFactory ncf;
public NikeProxyFactory(NikeClothFactory ncf) {
this.ncf = ncf;
}
@Override
public void produceCloth() {
System.out.println("Receive proxy of Nike");
ncf.produceCloth();
}
}
public class TestClothProduct {
public static void main(String[] args) {
NikeClothFactory ncf = new NikeClothFactory();
NikeProxyFactory npf = new NikeProxyFactory(ncf);
npf.produceCloth();
}
}
动态代理。
interface ClothFactory2 {
void produceCloth();
}
// 被代理类
class NikeFactory implements ClothFactory2 {
@Override
public void produceCloth() {
System.out.println("NikeFactory");
}
}
// InvocationHandler
class MyInvocationHandler implements InvocationHandler {
private Object obj; // 被代理类的对象
public Object blind(Object obj) {
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(obj, args);
}
}
public class TestClothProduct2 {
public static void main(String[] args) {
// 1.被代理类的对象
NikeFactory nf = new NikeFactory(); // 被代理对象
// 2.创建一个实现了InvocationHandler接口的类的对象
MyInvocationHandler mih = new MyInvocationHandler();
// 3.调用blind()方法,动态地返回一个代理类的对象。
ClothFactory2 cf = (ClothFactory2) mih.blind(nf); // 代理对象
// 4.转到对InvocationHandler接口的实现类的invoke()方法的调用
cf.produceCloth();
}
}
2. 面向切面编程
AOP代理:可以在执行目标方法之前、之后插入一些通用处理。
interface Human {
void info();
void fly(String str);
}
// 被代理类
class SuperMan implements Human {
@Override
public void info() {
System.out.println("INFO");
}
@Override
public void fly(String str) {
System.out.println("FLY" + str);
}
}
class SuperManProxy {
// 获得代理类
public static Object getProxyObject(Object object) {
MyInvocationHandler mih = new MyInvocationHandler();
mih.setObject(object); // 注意这里的小细节。
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), mih);
}
}
// InvocationHandler
class MyInvocationHandler implements InvocationHandler {
private Object object;
public void setObject(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
HumanUtil humanUtil = new HumanUtil();
humanUtil.methodOne();
Object obj = method.invoke(object, args);
humanUtil.methodTwo();
return obj;
}
}
class HumanUtil {
public void methodOne() {
System.out.println("method-1");
}
public void methodTwo() {
System.out.println("method-2");
}
}
public class TestAOP {
public static void main(String[] args) {
SuperMan sm = new SuperMan();
Human h = (Human) SuperManProxy.getProxyObject(sm);
h.info();
System.out.println();
h.fly("higher");
/*
method-1
INFO
method-2
method-1
FLYhigher
method-2
*/
}
}