原理
使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
静态代理
package proxy;
/**
* 静态代理
* 特点: 代理类和被代理类在编译期间就确定下来,,
* 当需求改变时,不改变原本的代码 横向增强方法 类似aop
*/
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 BeClothFactory implements ClothFactory {
@Override
public void produceCloth() {
System.out.println("被代理对象");
}
}
public class StaticProxyTest {
public static void main(String[] args) {
//创建被代理对象
BeClothFactory be = new BeClothFactory();
//创建代理对象
ProxyClothFactory proxyClothFactory = new ProxyClothFactory(be);
proxyClothFactory.produceCloth();
}
}
动态代理
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//面向切面编程
class HumanUtil {
public void method1() {
System.out.println("=======方法1=========")
}
public void method2() {
System.out.println("=======方法2=========")
}
}
/**
* 动态代理举例
*/
interface Human {
String getBelief();
void eat(String food);
}
//被代理类
class SuperMan implements Human {
@Override
public String getBelief() {
return "can fly";
}
@Override
public void eat(String food) {
System.out.println("like" + food);
}
}
//动态代理
/*
1.如何根据加载到内存中的类动态创建对象
2.通过代理类的对象调用方法时,如何动态调用被代理类方法
*/
class ProxyFactory {
//调用次方法,返回一个代理类的对象,解决问题一
public static Object getProxyInstance(Object obj) {
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces() ,new InvocationHandler(){
//通过调用代理类的对象 调用方法a时,就会自动调用如下的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增强方法
//obj 被代理对象,args 参数,method方法
HumanUtil util = new HumanUtile();
util.method1();//横向增强
Object interval = method.invoke(obj,args);
System.out.println("动态代理方法的增强,被增强的方法具有一些统一的特性,");
return interval;
}
});
}
}
public class DynamicProxy {
public static void main(String[] args) {
Human human = new SuperMan();
Human humanProxy = (Human) ProxyFactory.getProxyInstance(human);
humanProxy.eat("啥啥啥"); //调用方法的时候 会执行上面invoke方法
//System.out.println(humanProxy);
System.out.println(humanProxy.getBelief());
System.out.println("*******************");
BeClothFactory be = new BeClothFactory();
ClothFactory beProxy = (ClothFactory) ProxyFactory.getProxyInstance(be);
beProxy.produceCloth();
}
}
cglib
public class Client {
public static void main(String[] args) {
//创建目标对象
TeacherDao teacherDao = new TeacherDao();
ProxyFactory proxyFactory = new ProxyFactory(teacherDao);
//获取代理对象,并将目标对象传递给代理对象
TeacherDao target = (TeacherDao) proxyFactory.getProxyInstance();
//执行代理对象方法,触发intecept方法,从而实现对目标对象的调用
target.teach();
}
}
public class ProxyFactory implements MethodInterceptor {
//维护一个目标对象
private Object target;
//构造器 传入一个被代理的对象
public ProxyFactory(Object target) {
this.target=target;
}
//返回一个代理对象 是target的代理对象
public Object getProxyInstance(){
//创建一个工具类
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(target.getClass());
//设置回调函数
enhancer.setCallback(this);
//创建子类对象 即代理对象
return enhancer.create();
}
//重写 intercept方法 ,会调用目标对象的方法
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Cglib代理模式开始");
Object returnval =method.invoke(target,objects);
return returnval;
}
}
public class TeacherDao {
public void teach(){
System.out.println("授课ing cglib代理不需要实现借口");
}
}