0
点赞
收藏
分享

微信扫一扫

c# winform 创建日志登录界面

b91bff6ffdb5 2024-08-04 阅读 29

目录

1.代理模式介绍

2. 静态代理

3.动态代理

3.1 JDK动态代理

3.2 CGLIB动态代理

4. 动态代理和静态代理的区别


1.代理模式介绍

 通过一张图来了解代理模式:在这张图中,房东要出租房,我要租房,但是房东不想去搞一系列复杂的事情,于是找了一个代理的中介角色,客户直接和中介去租房就可以。房东和代理中介有一个共同的接口就是出租房。

2. 静态代理

以上面事件为例,实现静态代理

(1)首先定义一个接口House,定义一个租房的方法 rent()

package com.its.ex02.poxy01;

public interface House {
    /*
       1. 静态代理:
    *       以房东出租房子为例:
            房东,被代理的人。中介:代理人。租客:需要与被代理人沟通的人。
    * */
    void rent();
}

(2)定义一个实现类,代表房东,实现接口方法

package com.its.ex02.poxy01;

public class MyHouse implements House{
    @Override
    public void rent() {
        System.out.println("我要出租房子");
    }
}

(3)定义一个代理对象,用于帮被代理人出租房子

package com.its.ex02.poxy01;

public class Poxy implements House {
    private House ownerHouse;

    public Poxy(House ownerHouse) {
        this.ownerHouse = ownerHouse;
    }

    @Override
    public void rent() {
        lookHouse();
        talkPrice();
        //帮被代理人出租房子
        ownerHouse.rent();
        takeMoney();

    }
  //代理对象也可以有自己的一些功能
  private void lookHouse(){
      System.out.println("带客户去看房子");
  }
    private void talkPrice(){
        System.out.println("跟客户谈价格");
    }
    private void takeMoney(){
        System.out.println("拿提成");
    }
}

(4)执行测试,租客直接找代理人租房即可

package com.its.ex02.poxy01;

public class Client {
    public static void main(String[] args) {
//        找房子的客户
        MyHouse client = new MyHouse();
//        通过代理人租房
        Poxy poxy = new Poxy(client);
//        代理人给客户租房,其中也能做自己的事情
        poxy.rent();
    }
}

测试结果如下,静态代理完成。

3.动态代理

3.1 JDK动态代理

(1)首先定义一个接口House,定义一个租房的方法 rent()写一个

package com.its.ex02.poxy02;

public interface House {
    void rent();
}

(2)然后定义一个房东类实现这个接口,重写租房的方法。

package com.its.ex02.poxy02;

public class MyHouse implements House {
    @Override
    public void rent() {
        System.out.println("我要出租房子");
    }
}

(3)定义proxyJDK这个类,这个类实现了 InvocationHandler 接口,它是用来处理代理对象方法调用的。

package com.its.ex02.poxy02;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;


//这个类实现了 InvocationHandler 接口,它是用来处理代理对象方法调用的
public class PoxyJDK implements InvocationHandler {
    private House house;

//    这个构造函数接收一个 House 类型的对象,并将其赋值给成员变量 house
//    接口类型的好处是只要实现了House接口的实现类都可以被代理
    public PoxyJDK(House house) {
        this.house = house;
    }

    //实现InvocationHandler接口,用于处理 代理对象上(房东) 的方法调用。
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用方法前可以执行动态代理人自己的事情");
        //使用反射机制调用实际对象 House接口 上的方法。
        Object o = method.invoke(house, args);
        System.out.println("调用方法后也可以执行动态代理人自己的事情");
        //返回方法调用的结果
        return o;
    }
}

(4)定义一个客户类,用于演示如何创建代理对象并调用其方法。

package com.its.ex02.poxy02;

import java.lang.reflect.Proxy;

public class Client {
    public static void main(String[] args) {
        //1.被代理的类
        MyHouse myHouse = new MyHouse();
        //2.代理类, 创建一个 PoxyJDK 实例,传入 myHouse 作为被代理对象。
        PoxyJDK poxyJDK = new PoxyJDK(myHouse);
        //3.获取myHouse的类加载器接口,这是使用 Proxy.newProxyInstance 方法创建代理对象所必需的
        ClassLoader classLoader = MyHouse.class.getClassLoader();
        //4.获取 MyHouse 类实现的所有接口,通常这里只有一个接口,即 House
        Class<?>[] interfaces = MyHouse.class.getInterfaces();
        //5.使用 Proxy.newProxyInstance 方法创建代理对象 house
        House house = (House) Proxy.newProxyInstance(classLoader, interfaces, poxyJDK);
        //调用代理对象的 rent 方法。
        house.rent();
    }
}

(5)执行测试代码,结果如下,演示成功

3.2 CGLIB动态代理

CGLIB概念

原理

(1)首先定义一个接口House,定义一个租房的方法 rent()写一个

package com.its.ex02.poxy03;

public interface House {
    void rent();
}

(2)然后定义一个房东类实现这个接口,重写租房的方法。

package com.its.ex02.poxy03;

public class MyHouse implements House {
    @Override
    public void rent() {
        System.out.println("我要出租房子");
    }
}

(3)接下来,我们需要创建一个实现了 MethodInterceptor 接口的类PoxyCGLIB,用于处理方法调用。

package com.its.ex02.poxy03;

import com.its.ex02.poxy01.House;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class poxyCGLIB implements MethodInterceptor {
    public House house;

    public poxyCGLIB(House house) {
        this.house = house;
    }
    /*
        o: 当前代理对象实例。
        method: 被调用的方法的 Method 对象。
        objects: 被调用的方法的参数列表。
        methodProxy: 用于调用原始方法的代理对象。
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("执行方法前做的事情,方法名:"+method.getName());
        Object result = methodProxy.invoke(house, objects);
        System.out.println("执行方法后做的事情方,法名:"+method.getName());
        return result;
    }
}

(4)定义一个客户类,用于测试创建代理对象并调用代理对象的方法。

package com.its.ex02.poxy03;
import com.its.ex02.poxy03.House;
import org.springframework.cglib.core.DebuggingClassWriter;
import org.springframework.cglib.proxy.Enhancer;

public class Client {
    public static void main(String[] args) {
        MyHouse myHouse = new MyHouse();

        // 代理类class文件存入本地磁盘方便我们反编译查看源码
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,
                "D:\\code");
        // Enhancer 是 CGLIB 中用于创建代理对象的类。
        Enhancer enhancer = new Enhancer();
        // 设置 Enhancer 的父类为 MyHouse 类,这表示代理类将继承 MyHouse 类。
        enhancer.setSuperclass(MyHouse.class);
        // 设置enhancer的回调对象
        enhancer.setCallback(new poxyCGLIB(myHouse));
        // 创建代理对象,类型转换为 House 接口
        House house = (House) enhancer.create();
        // 通过代理对象调用目标方法
        house.rent();
    }
}

4. 动态代理和静态代理的区别

动态代理可以动态的生成代理类,静态代理则需要预先定义代理类,对于每一个接口都需要有一个对应的代理类,下面举例说明。

静态代理

// ServiceA 接口
public interface ServiceA {
    void doSomethingA();
}

// ServiceB 接口
public interface ServiceB {
    void doSomethingB();
}

// ServiceA 的实现
public class ServiceAImpl implements ServiceA {
    @Override
    public void doSomethingA() {
        System.out.println("Doing something A...");
    }
}

// ServiceB 的实现
public class ServiceBImpl implements ServiceB {
    @Override
    public void doSomethingB() {
        System.out.println("Doing something B...");
    }
}

// ServiceA 的静态代理类
public class ServiceAProxy implements ServiceA {
    private ServiceA serviceA;

    public ServiceAProxy(ServiceA serviceA) {
        this.serviceA = serviceA;
    }

    @Override
    public void doSomethingA() {
        System.out.println("Before doSomethingA");
        serviceA.doSomethingA();
        System.out.println("After doSomethingA");
    }
}

// ServiceB 的静态代理类
public class ServiceBProxy implements ServiceB {
    private ServiceB serviceB;

    public ServiceBProxy(ServiceB serviceB) {
        this.serviceB = serviceB;
    }

    @Override
    public void doSomethingB() {
        System.out.println("Before doSomethingB");
        serviceB.doSomethingB();
        System.out.println("After doSomethingB");
    }
}

动态代理

// 公共的日志记录 InvocationHandler
public class LoggingInvocationHandler implements InvocationHandler {
    private Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method call: " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("After method call: " + method.getName());
        return result;
    }
}

// 创建代理对象并使用
public class ProxyDemo {
    public static void main(String[] args) {
        ServiceA serviceA = new ServiceAImpl();
        ServiceA serviceAProxy = (ServiceA) Proxy.newProxyInstance(
                ServiceA.class.getClassLoader(),
                new Class<?>[]{ServiceA.class},
                new LoggingInvocationHandler(serviceA)
        );
        
        ServiceB serviceB = new ServiceBImpl();
        ServiceB serviceBProxy = (ServiceB) Proxy.newProxyInstance(
                ServiceB.class.getClassLoader(),
                new Class<?>[]{ServiceB.class},
                new LoggingInvocationHandler(serviceB)
        );

        serviceAProxy.doSomethingA();
        serviceBProxy.doSomethingB();
    }
}
举报

相关推荐

0 条评论