代理模式(静态代理和动态代理)

代理模式(静态代理和动态代理)


前言

应用场景:
1,因为某些原因无法直接操作目标类对象
eg. 比如登录某个网站时,有时候是被授权的管理员才能登录,一般用户是无法登录的,这个时候如果一般用户想要进行操作,就需要用到代理模式,将自己要进行的操作交给管理员来代理
2,对较多方法执行相同的操作
eg.比如在执行一些列方法之前添加开始日志,方法结束之后添加结束日志等功能。使用代理模式,降低了业务代码和目标方法的耦合度。提高了代码的性能,而且还解决了代码的大量冗余

一、静态代理是什么?

静态代理常常有一个接口,一个目标类,一个代理类,目标类和代理类需要实现同一个接口
静态代理也就是在程序运行前就已经存在代理类的字节码文件,代理类和目标类类的关系在运行前就确定了

1.定义接口

package com.wt.service;

import com.wt.pojo.User;

public interface UserService {
    int addUser(User user);
    int deleteUser(int id);
}

2.定义目标类(功能是模拟的)

package com.wt.service.impl;

import com.wt.pojo.User;
import com.wt.service.UserService;

public class UserServiceImpl implements UserService {
    @Override
    public int addUser(User user) {
        System.out.println("新增到数据库一个新用户");
        return 1;
    }

    @Override
    public int deleteUser(int id) {
        System.out.println("删除一个用户");
        return 1;
    }
}

3.定义代理类

package com.wt.proxy;

import com.wt.pojo.User;
import com.wt.service.UserService;
import com.wt.service.impl.UserServiceImpl;
import com.wt.tx.Transacation;

public class UserServiceProxy implements UserService {
    Transacation tx=new Transacation();
    UserService userService=new UserServiceImpl();
    @Override
    public int addUser(User user) {
        tx.TXopen();
        userService.addUser(user);
        tx.TXclose();
        return 1;
    }

    @Override
    public int deleteUser(int id) {
        tx.TXopen();
        userService.deleteUser(id);
        tx.TXclose();
        return 1;
    }
}

4.定义事务类

package com.wt.tx;

public class Transacation {
    public void TXopen(){
        System.out.println("今天开始工作");
    }
    public void TXclose(){
        System.out.println("今天下班了");
    }
}

5.测试代码


import com.wt.pojo.User;
import com.wt.proxy.UserServiceProxy;
import com.wt.service.UserService;
import com.wt.service.impl.UserServiceImpl;
import org.junit.jupiter.api.Test;

public class TestUser {
    @Test
    public void Test1(){
        UserService userService= new UserServiceProxy();
        User user= new User();
        userService.addUser(user);
        System.out.println("=================");
        userService.deleteUser(1);
    }
}

6.测试结果

在这里插入图片描述

二、动态代理

动态代理:对于一个实现了一个接口的类(目标类,委托类i)增加一些其他的方法比如日志,事务等。可以给这个类创建一个代理类来完成这个操作,代理类需要实现相同的接口,这种方法降低了代码的耦合度。它与静态代理的区别是:动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。

1.相关方法

1.1Proxy类

它是JDK封装的类,对于动态代理,调用Proxy.newProxyInstance()方法创建代理对象
它包含3个参数
第一个参数:目标类的Class获取
第二个参数:目标类的接口获取
第三个参数:拦截器(实现Invocationhandle接口的类实例)

1.2new InvocationHandler()匿名类

是实现lInvocationhandle接口的实例,该实例会调用接口中的方法invoke()

1.3invoke()

invoke()是Invocationhandle接口中定义的方法,实现了该接口的实现类需要重写这个方法,该方法有三个参数,第一个Proxy可以通过它反射获取代理对象信息,第二个method通过该方法可以执行目标类对象中的方法,第三个参数args是一个数组参数,表示目标对象方法中的参数

2.实现步骤

2.1创建接口

package com.wt.pojo;

public interface Person {
    void giveMoney();
}

2.2创建目标对象类

package com.wt.pojo;
//被代理类
public class Student implements Person{
    @Override
    public void giveMoney() {
        System.out.println("学生王宝强,上交班费");
    }
}

2.3测试类中创建生成代理对象

package com.wt.test;

import com.wt.pojo.Person;
import com.wt.pojo.Student;
import org.junit.jupiter.api.Test;

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

public class TestPerson {
    @Test
    public void test1(){
        //创建目标类对象
        final Person s1=new Student();
        //获取一个代理对象
       Person p1=(Person) Proxy.newProxyInstance(s1.getClass().getClassLoader(), s1.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("这位同学最近表现不错!");
               Object result= method.invoke(s1,args);
                System.out.println("老师他交了班费,学习也比较好,您应该表扬他");
                return result;
            }
        });
       p1.giveMoney();
    }
}

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

三,运行结果

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值