静态代理动态代理的理解

静态代理动态代理的理解,第1张

静态代理/动态代理的理解

设计模式:计算机程序的设计总结 代码的编写 设计 为了提高代码的问题

  • 1.解决资源共享问题 单例 工厂模式

  • 2.代码的拓展问题 代理模式 装饰器模式 适配器模式
    二次开发:

  • 3.解决依赖(对象)创建:工厂 建造者模式

  • 代理模式:解决代码拓展问题 功能的增强/改变
    代理人: 去做事的人
    被代理人:委托代理人做事的人

  • 代理类:
    被代理类:
    静态代理: 指代理类,对象都需要程序要手动编写代码
    动态代理:代理类,对象都是由程序自动生成 不需要程序员手写代理类代码

静态代理:需要遵守以下条件

  • 1.需要一个公共的接口
  • 2…被代理类需要实现该接口
  • 3.代理类也需要实现该接口
  • 4.代理类必须保持一个被代理对象(被代理类的对象)
  • 5.代理类中的方法必须调用被代理类中对应的方法
  • 6.代理类中增强的代码需要在调用被代理类的方法的前后执行
    静态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//1.公共接口
interface UserService{
    public  void addUser();
}

//2.被代理类
class  UserServiceImpl implements UserService{

    @Override
    public void addUser() {
        System.out.println("调用mapper执行sql");
    }
}
//3.代理类
class  UserServiceProxy implements  UserService{
    //4.保持一个被代理对象
private  UserService userService;

    public UserServiceProxy(UserService userService) {
        super();
        this.userService = userService;
    }

    @Override
    public void addUser() {
       //6.代理类中增强的代码需要在调用被代理类的方法的前后执行
        System.out.println("开启事务");
         //5.调用被代理对象的方法
        
        try{
         //代理类中的方法必须调用被代理类中对应的方法
            userService.addUser();
            System.out.println("提交事务");
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("回滚");
        }

    }
}
public class Test {
    public static void main(String[] args) {
        //创建代理类对象
        UserService userService = new UserServiceProxy( new UserServiceImpl());
        //使用
        userService.addUser();
    }
}

JDK实现动态代理

  • JDK使用方法
  • 1.需要一个公共的接口
  • 2.被代理类需要实现该接口
  • 3.创建一个代理类工厂
    3.1.工厂需要保持一个被代理类对象
    3.2.需要指定一个方法,该方法用来返回一个代理类对象

JDK代理生成的代理类是实现了被代理类上所有接口的子类,以下代码为例:

  • 生成的$Proxy0类是OrderServiceImpl的代理类,该类实现了OrderService接口,当通过该类对象调用相关方法时,会自动调用InvocationHandler中的invoke方法,将代理类对象、要调用的方法及相关参数作为形参传递到invoke方法中来
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 接口
interface OrderService{
    public boolean delOrder(int id);
}

// 被代理类
class OrderServiceImpl implements OrderService{
    @Override
    public boolean delOrder(int id) {
        System.out.println("执行SQL:" + id);
        return true;
    }
}

// 代理类工厂
class ProxyFactory{
    // 保持一个被代理类对象
    private Object target;

    public ProxyFactory(Object target) {
        super();
        this.target = target;
    }

    // 提供方法,返回代理类对象
    public Object getProxy() {
        // 调用API创建代理类对象
        // 参数1:类加载器
        // 参数2:被代理类实现的接口
        // 参数3:调用处理器,编写增强的代码
        return Proxy.newProxyInstance(
                ProxyFactory.class.getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    // 参数1:代理类对象
                    // 参数2:即将被调用的方法
                    // 参数3:调用method方法的参数
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("-------------------");

                        System.out.println(proxy.getClass());
                        System.out.println(method.getName());
//						for (Object arg : args) {
//							System.out.println(arg);
//						}

                        System.out.println("-------------------");
                        System.out.println("开启事务");

                        //调用被代理类对象的方法
                        Object result = method.invoke(target, args);

                        System.out.println("提交事务");

                        // 返回被代理类对象对应方法的返回值
                        return result;
                    }
                });
    }
}


public class Test{
    public static void main(String[] args) {
        // 创建被代理类对象
        OrderService target = new OrderServiceImpl();

        // 创建工厂
        ProxyFactory factory = new ProxyFactory(target);

        // 得到代理类对象
        Object proxy = factory.getProxy();

        System.out.println(proxy.getClass());  //  $Proxy0  JDK代理生成的类

        if (proxy instanceof OrderService) {
            System.out.println("YES");

            OrderService orderService = (OrderService)proxy;

            //
            System.out.println(orderService.delOrder(1002));

        }
    }
}`

CGLIB动态代理
cglib代理又称作子类代理
生成的类是被代理类的子类 自动生成一个代理类 该代理类继承了被代理类
只要代理类不是被final修饰 都可以通过cglib代理生成代理类,对象

  • 1.需要非final修饰的代理类
  • 2.创建一个工厂类,
    2.1工厂类也需要保持一个代理类对象
    2.2指定一个方法,该方法要返回代理类对象
    ------需要导入两个包
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

  class  AddressServiceImpl{
    public boolean address(String address){
        System.out.println("添加地址");
        return true;
    }
}

//工厂
class  CglibFactory{
    //代理类对象
    private Object target;

    public CglibFactory(Object target) {
        this.target = target;
    }



    //提供方法
    public  Object getProxy(){
        //1.创建一个工具类对象
        Enhancer enhancer = new Enhancer();
        //2.设置代理类的父类
        enhancer.setSuperclass(target.getClass());
        //3.设置处理的方法
        enhancer.setCallback(new MethodInterceptor() {
            //参数
            @Override
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println("开启事务");
                //调用被代理类的方法
                Object result = method.invoke(target,args);
                System.out.println("提交事务");
                return result;
            }
        });
        //创建代理类对象
        return  enhancer.create();
    }
}
public class Test {
    public static void main(String[] args) {
        //1.创建被代理对象
        AddressServiceImpl addressServiceImpl = new AddressServiceImpl();
        //2.创建工厂
        CglibFactory  factory = new CglibFactory(addressServiceImpl);
        //3.调方法创建代理类对象
        Object proxy = factory.getProxy();
        System.out.println(proxy.getClass());//$$EnhancerByCGLIB$b5f61aa   CGLIB动态代理创建
        if(proxy instanceof  AddressServiceImpl){
            System.out.println("YES");
            addressServiceImpl = (AddressServiceImpl)proxy;
            //调方法
            addressServiceImpl.address("地球村");
         }
    }
}

JDK代理和CGLIB代理的区别

  • 1.一个是JDK自带的 一个是第三方的
  • 2.JDK代理要求被代理类必须实现接口 而CGLIB不需要
  • 3.JDK代理生成的代理类是被代理类实现接口的子类。代理类需要需要实现这些接口, 而CGLIB生成的代理是被代理类的子类,代理类直接继承被代理类

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5684822.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存