JDK动态代理

实例:让中介帮忙买车子和买房子

买车和买房

  1. public interface IBuy {
  2. void buyHouse();
  3. void buyCar();
  4. }

然后实现接口

  1. public class BuyImpl implements IBuy {
  2. @Override
  3. public void buyHouse() {
  4. System.out.println("我要买房");
  5. }
  6. @Override
  7. public void buyCar() {
  8. System.out.println("我要买车子");
  9. }
  10. }

动态代理工厂类:

  1. public class ProxyFactory {
  2. /**
  3. * 单例模式的
  4. */
  5. private ProxyFactory(){ }
  6. private static ProxyFactory proxyFactory = new ProxyFactory();
  7. public static ProxyFactory getInstance(){
  8. return proxyFactory;
  9. }
  10. /**
  11. * Jdk动态代理
  12. * @param obj 委托对象
  13. * @return 代理对象
  14. */
  15. public Object getJdkProxy(Object obj){
  16. return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),
  17. new InvocationHandler() {
  18. @Override
  19. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  20. Object invoke = null;
  21. System.out.println("委托给中介代理");
  22. invoke = method.invoke(obj, args);
  23. System.out.println("给回扣");
  24. return invoke;
  25. }
  26. });
  27. }
  28. }

JdkProxy测试类执行:

  1. public class JdkProxy {
  2. public static void main(String[] args) {
  3. IBuy iBuy = new BuyImpl();
  4. IBuy jdkProxy = (IBuy) ProxyFactory.getInstance().getJdkProxy(iBuy);
  5. jdkProxy.buyHouse();
  6. System.out.println("----------");
  7. jdkProxy.buyCar();
  8. }
  9. }

结果:
动态代理模式(实例3) - 图1

Cglib动态代理

pom文件引入依赖

  1. <!--引入cglib依赖-->
  2. <dependency>
  3. <groupId>cglib</groupId>
  4. <artifactId>cglib</artifactId>
  5. <version>2.1_2</version>
  6. </dependency>

修改ProxyFactory工厂,添加cglib代理

  1. ······
  2. ······
  3. ······
  4. /**
  5. * 使用cglib动态代理生成代理对象
  6. * @param obj 委托对象
  7. * @return
  8. */
  9. public Object getCglibProxy(Object obj) {
  10. return Enhancer.create(obj.getClass(), new MethodInterceptor() {
  11. @Override
  12. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  13. Object result = null;
  14. System.out.println("委托给中介代理交2000元");
  15. result = method.invoke(obj,objects);
  16. System.out.println("给回扣两个点");
  17. return result;
  18. }
  19. });
  20. }
  21. ······
  22. ······
  23. ······

Cglib测试类执行:

  1. public class CglibProxy {
  2. public static void main(String[] args) {
  3. BuyImpl buy = new BuyImpl(); // 委托对象
  4. // 获取rentingHouse对象的代理对象,
  5. // Enhancer类似于JDK动态代理中的Proxy
  6. // 通过实现接口MethodInterceptor能够对各个方法进行拦截增强,类似于JDK动态代理中的InvocationHandler
  7. // 使用工厂来获取代理对象
  8. BuyImpl cglibProxy = (BuyImpl) ProxyFactory.getInstance().getCglibProxy(buy);
  9. cglibProxy.buyCar();
  10. System.out.println("----------");
  11. cglibProxy.buyHouse();
  12. }
  13. }

结果:
动态代理模式(实例3) - 图2

注意

JDK动态代理中,我们必须使用接口。而Cglib则不需要。

注意观察上例中两个测试列的区别即可:

JDK IBuy iBuy = new BuyImpl();

Cglib BuyImpl buy = new BuyImpl();