八: 动态代理的几种实现方式及优缺点

绝地灬酷狼 2022-02-04 13:47 379阅读 0赞
  1. 动态代理

    在这里插入图片描述
    学的有点蒙,。。。。。后续再写吧。。。。。。

JDK 代码示例: 需求, user 实体类 值写入到数据库时, 校验name 长度不能小于1
无侵入性增强

  1. 有个接口 UserService

    package com.enjoylearning.dynamic.proxy.jdk;

    import com.enjoylearning.dynamic.proxy.User;

    public interface UserService {

    1. void addUser(User user);

    }

  2. 被增强的类必须要继承接口

    package com.enjoylearning.dynamic.proxy.jdk;

    import com.enjoylearning.dynamic.proxy.User;

    public class UserServiceImpl implements UserService {

    1. @Override
    2. public final void addUser(User user) {
    3. System.out.println("用户数据入库成功,数据为:" + user.toString());
    4. }

    }

3.拦截器

  1. package com.enjoylearning.dynamic.proxy.jdk;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.util.logging.Logger;
  5. import com.enjoylearning.dynamic.proxy.User;
  6. public class UserServiceInterceptor implements InvocationHandler{
  7. private Object realObj;
  8. private static Logger logger = Logger.getLogger(UserServiceInterceptor.class.getName());
  9. public Object getRealObj() {
  10. return realObj;
  11. }
  12. public void setRealObj(Object realObj) {
  13. this.realObj = realObj;
  14. }
  15. public UserServiceInterceptor(Object realObj) {
  16. super();
  17. this.realObj = realObj;
  18. }
  19. public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
  20. if(args!=null && args.length>0 && args[0] instanceof User){
  21. User user = (User) args[0];
  22. if(user.getName().trim().length()<=1){
  23. throw new RuntimeException("用户姓名输入长度需要大于1!");
  24. }
  25. }
  26. Object ret = method.invoke(realObj, args);
  27. logger.info("数据库操作成功!");
  28. return ret;
  29. }
  30. }

4.测试方法

  1. package com.enjoylearning.dynamic.proxy.jdk;
  2. import java.lang.reflect.Proxy;
  3. import com.enjoylearning.dynamic.proxy.User;
  4. public class Client {
  5. public static void main(String[] args) {
  6. User user = new User();
  7. user.setAddress("地址");
  8. user.setAge(20);
  9. user.setName("1ison");
  10. UserService us = new UserServiceImpl();
  11. UserServiceInterceptor usi = new UserServiceInterceptor(us);
  12. //1.类加载器
  13. //2. 服务接口信息
  14. //3. invocationhandler 本身
  15. UserService proxy = (UserService) Proxy.newProxyInstance(us.getClass().getClassLoader(), us.getClass().getInterfaces(), usi);
  16. //通过动态代理增强业务
  17. proxy.addUser(user);
  18. // System.out.println("---------------------");
  19. // System.out.println(proxy.hashCode());
  20. }
  21. }

CGLIB 动态代理

在这里插入图片描述
1.被增强的 方法, 不需要继承接口

  1. package com.enjoylearning.dynamic.proxy.cglib;
  2. import com.enjoylearning.dynamic.proxy.User;
  3. public class UserServiceImpl {
  4. public final void addUser(User user) {
  5. System.out.println("用户数据入库成功,数据为:"+user.toString());
  6. }
  7. }

2.拦截器 实现intercept 方法

  1. package com.enjoylearning.dynamic.proxy.cglib;
  2. import java.lang.reflect.Method;
  3. import java.util.logging.Logger;
  4. import com.enjoylearning.dynamic.proxy.User;
  5. import net.sf.cglib.proxy.MethodInterceptor;
  6. import net.sf.cglib.proxy.MethodProxy;
  7. public class UserServiceInterceptor implements MethodInterceptor {
  8. private static Logger logger = Logger.getLogger(UserServiceInterceptor.class.getName());
  9. public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {
  10. if(args!=null && args.length>0 && args[0] instanceof User){
  11. User user = (User) args[0];
  12. if(user.getName().trim().length() <= 1){
  13. throw new RuntimeException("用户姓名输入长度需要大于1!");
  14. }
  15. }
  16. Object ret = proxy.invokeSuper(obj, args);
  17. logger.info("数据库操作成功!");
  18. return ret;
  19. }
  20. }
  1. 测试类

    package com.enjoylearning.dynamic.proxy.cglib;

    import com.enjoylearning.dynamic.proxy.User;

    import net.sf.cglib.proxy.Enhancer;

    public class Client {

    1. public static void main(String[] args) {
    2. User user = new User();
    3. user.setAddress("地址");
    4. user.setAge(20);
    5. user.setName("lison");
    6. Enhancer enhancer = new Enhancer();
    7. enhancer.setSuperclass(UserServiceImpl.class);
    8. enhancer.setCallback(new UserServiceInterceptor());
    9. UserServiceImpl usi1 = (UserServiceImpl) enhancer.create();
    10. usi1.addUser(user);

    // System.out.println(“——————————-“);
    // System.out.println(usi.hashCode());

    // UserServiceImpl us = new UserServiceImpl();
    // enhancer.setCallback(new UserServiceDelegateInterceptor(us));
    // UserServiceImpl usi2 = (UserServiceImpl) enhancer.create();
    // usi2.addUser(user);

    1. }

    }

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,379人围观)

还没有评论,来说两句吧...

相关阅读

    相关 动态代理方式

    1、动态代理概述 代理类Proxy和RealSubject应该实现了相同的功能接口,在面向对象的编程之中,如果想要两个对象实现相同的功能,有以下两种方式: 1. 1)

    相关 Java动态代理实现方式

    动态代理是为了实现在不改变源码的基础上,对已有方法增强,它是AOP思想的底层实现技术。一般而言,动态代理有以下两种实现方式 一、基于接口的动态代理(JDK动态代理) 要...