java-动态代理

为什么需要代理?

在这里插入图片描述

如何创建代理

注意:实现类和代理需要实现同一个接口

在这里插入图片描述

接口

public interface Star {
    String sing(String song);

    void dance();
}

实现类

public class BigStar implements Star {
    private String name;

    public BigStar(String name) {
        this.name = name;
    }

    public String sing(String song) {
        System.out.println(name + " is singing " + song);
        return "success";
    }

    public void dance() {
        System.out.println(name + " is dancing " );
    }
}

代理类

public class ProxyUtil {
    public static Star createProxy(Star target) {
        /**
         * ClassLoader loader, 加载类的类加载器 一般使用当前类的类加载器
         * Class<?>[] interfaces, 代理类要实现的接口列表 有哪些方法需要代理
         * InvocationHandler h 代理类的调用处理程序 实现接口 怎么代理这些方法
         */
        Star starProxy = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
                new Class[]{Star.class},
                // 代理类的调用处理程序
                new InvocationHandler() {
                    @Override
                    // 参数一:代理对象 参数二:当前调用的方法 参数三:方法的参数
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object result = null;
                        if ("sing".equals(method.getName())) {
                            beforeSing();
                            result = method.invoke(target, args);
                            afterSing();
                        } else if ("dance".equals(method.getName())) {
                            beforeDance();
                            result = method.invoke(target, args);
                            afterDance();
                        }
                        return result;
                    }});
        return starProxy;
    }

    // 前置增强
    public static void beforeSing() {
        System.out.println("唱歌之前");
    }

    // 后置增强
    public static void afterSing() {
        System.out.println("唱歌之后");
    }

    // 前置增强
    public static void beforeDance() {
        System.out.println("跳舞之前");
    }

    // 后置增强
    public static void afterDance() {
        System.out.println("跳舞之后");
    }
}

使用代理对象

  • 生成实现类对象
  • 将实现类对象传递给代理对象
  • 使用代理对象调用对应的方法(代理对象不仅会调用原本实现类的方法,还会调用前置增强和后置增强)
// 生成具体的类
Star star = new BigStar("Jay");
// 生成代理类
Star proxy = ProxyUtil.createProxy(star);

String sing = proxy.sing("七里香");
System.out.println(sing );
proxy.dance();

实际案例

需求

在这里插入图片描述

接口

public interface UserService {

    // 登录功能
    void login(String username, String password) throws Exception;

    // 删除功能
    void delete() throws Exception;

    // 查询功能
    String[] selectUsers() throws Exception;
}

实现类

public class UserServiceImpl implements UserService{
    @Override
    public void login(String username, String password) throws Exception {


        if ("admin".equals(username) && "123456".equals(password)) {
            System.out.println("登录成功");
        } else {
            System.out.println("登录失败");
        }

        Thread.sleep(1000);

    }

    @Override
    public void delete() throws Exception {


        System.out.println("删除用户");

        Thread.sleep(1500);


    }

    @Override
    public String[] selectUsers() throws Exception {

        System.out.println("查询用户");
        String[] users = new String[]{"张三", "李四", "王五"};

        Thread.sleep(2000);


        return users;
    }
}
 

代理类

public class ProxyUtil {
    public static  UserService createProxy(UserService target) {

        // 如果只执行了原本的方法,但是没有执行前置增强和后置增强,那么就是没有代理成功
        // 原因一般是返回了最开始的target对象,而不是代理对象
        return (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
                new Class[]{UserService.class},
                (proxy, method, args) -> {
                    Object result = null;
                    long start = before();
                    result = method.invoke(target, args);
                    long end = after();
                    takeTime(start, end);
                    return result;
                });

    }

    private static long before() {
        System.out.println("前置增强");
        return System.currentTimeMillis();
    }

    private static long  after() {
        System.out.println("后置增强");
        return System.currentTimeMillis();
    }

    private static void takeTime(long start,long end) {
        System.out.println("耗时:" + (end - start)/1000 + "s");
    }

}

使用

public class Main {
    public static void main(String[] args) throws Exception {
        UserService userService = new UserServiceImpl();
        UserService proxy = ProxyUtil.createProxy(userService);
        proxy.login("admin", "123456");
        proxy.delete();
        proxy.selectUsers();
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值