原理

使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。

静态代理

  1. package proxy;
  2. /**
  3. * 静态代理
  4. * 特点: 代理类和被代理类在编译期间就确定下来,,
  5. * 当需求改变时,不改变原本的代码 横向增强方法 类似aop
  6. */
  7. interface ClothFactory {
  8. void produceCloth();
  9. }
  10. //代理类
  11. class ProxyClothFactory implements ClothFactory {
  12. private ClothFactory factory; //用被代理对象实例化
  13. public ProxyClothFactory(ClothFactory factory) {
  14. this.factory = factory;
  15. }
  16. @Override
  17. public void produceCloth() {
  18. System.out.println("代理工厂做准备工作");
  19. factory.produceCloth();
  20. System.out.println("代理工厂结束");
  21. }
  22. }
  23. //被代理类
  24. class BeClothFactory implements ClothFactory {
  25. @Override
  26. public void produceCloth() {
  27. System.out.println("被代理对象");
  28. }
  29. }
  30. public class StaticProxyTest {
  31. public static void main(String[] args) {
  32. //创建被代理对象
  33. BeClothFactory be = new BeClothFactory();
  34. //创建代理对象
  35. ProxyClothFactory proxyClothFactory = new ProxyClothFactory(be);
  36. proxyClothFactory.produceCloth();
  37. }
  38. }

动态代理

  1. package proxy;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. //面向切面编程
  6. class HumanUtil {
  7. public void method1() {
  8. System.out.println("=======方法1=========")
  9. }
  10. public void method2() {
  11. System.out.println("=======方法2=========")
  12. }
  13. }
  14. /**
  15. * 动态代理举例
  16. */
  17. interface Human {
  18. String getBelief();
  19. void eat(String food);
  20. }
  21. //被代理类
  22. class SuperMan implements Human {
  23. @Override
  24. public String getBelief() {
  25. return "can fly";
  26. }
  27. @Override
  28. public void eat(String food) {
  29. System.out.println("like" + food);
  30. }
  31. }
  32. //动态代理
  33. /*
  34. 1.如何根据加载到内存中的类动态创建对象
  35. 2.通过代理类的对象调用方法时,如何动态调用被代理类方法
  36. */
  37. class ProxyFactory {
  38. //调用次方法,返回一个代理类的对象,解决问题一
  39. public static Object getProxyInstance(Object obj) {
  40. return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces() ,new InvocationHandler(){
  41. //通过调用代理类的对象 调用方法a时,就会自动调用如下的方法
  42. @Override
  43. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  44. //增强方法
  45. //obj 被代理对象,args 参数,method方法
  46. HumanUtil util = new HumanUtile();
  47. util.method1();//横向增强
  48. Object interval = method.invoke(obj,args);
  49. System.out.println("动态代理方法的增强,被增强的方法具有一些统一的特性,");
  50. return interval;
  51. }
  52. });
  53. }
  54. }
  55. public class DynamicProxy {
  56. public static void main(String[] args) {
  57. Human human = new SuperMan();
  58. Human humanProxy = (Human) ProxyFactory.getProxyInstance(human);
  59. humanProxy.eat("啥啥啥"); //调用方法的时候 会执行上面invoke方法
  60. //System.out.println(humanProxy);
  61. System.out.println(humanProxy.getBelief());
  62. System.out.println("*******************");
  63. BeClothFactory be = new BeClothFactory();
  64. ClothFactory beProxy = (ClothFactory) ProxyFactory.getProxyInstance(be);
  65. beProxy.produceCloth();
  66. }
  67. }

cglib

  1. public class Client {
  2. public static void main(String[] args) {
  3. //创建目标对象
  4. TeacherDao teacherDao = new TeacherDao();
  5. ProxyFactory proxyFactory = new ProxyFactory(teacherDao);
  6. //获取代理对象,并将目标对象传递给代理对象
  7. TeacherDao target = (TeacherDao) proxyFactory.getProxyInstance();
  8. //执行代理对象方法,触发intecept方法,从而实现对目标对象的调用
  9. target.teach();
  10. }
  11. }
  12. public class ProxyFactory implements MethodInterceptor {
  13. //维护一个目标对象
  14. private Object target;
  15. //构造器 传入一个被代理的对象
  16. public ProxyFactory(Object target) {
  17. this.target=target;
  18. }
  19. //返回一个代理对象 是target的代理对象
  20. public Object getProxyInstance(){
  21. //创建一个工具类
  22. Enhancer enhancer = new Enhancer();
  23. //设置父类
  24. enhancer.setSuperclass(target.getClass());
  25. //设置回调函数
  26. enhancer.setCallback(this);
  27. //创建子类对象 即代理对象
  28. return enhancer.create();
  29. }
  30. //重写 intercept方法 ,会调用目标对象的方法
  31. @Override
  32. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  33. System.out.println("Cglib代理模式开始");
  34. Object returnval =method.invoke(target,objects);
  35. return returnval;
  36. }
  37. }
  38. public class TeacherDao {
  39. public void teach(){
  40. System.out.println("授课ing cglib代理不需要实现借口");
  41. }
  42. }