spring(二)—手动实现:动态代理

代理对象的作用:完成原有功能的同时,借助代理对象添加额外的功能

​​代理:

  • 目标类(target):被代理的类(对象) 真正的业务逻辑实现
  • 代理类(proxy):添加额外的功能的类(对象)

​​开发原则:

  • 代理类和目标类必须实现统一接口
  • 代理类依赖于目标类

静态代理:

1.在程序运行之前手动为目标对象创建代理对象
2.静态代理存在的问题

  • ① 代码量加大,增加工作量
  • ② 解决方案:使用动态代理

以下为-开发静态代理类-配置静态代理类-最后通过调用静态代理类完成功能
开发静态代理类配置静态代理类

手动实现动态代理:

  • 在程序运行时,动态的创建代理对象

在这里插入图片描述

package test;

import org.junit.Test;
import service.AdminService;
import service.AdminServiceImpl;

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

public class DynamicProxy {
    /*
     * 动态代理
     *   原则:
     *       1. 目标类和代理类实现相同的接口
     *       2. 代理类依赖于目标类
     *   概念:
     *       程序运行过程中, 通过jdk→Proxy类, 动态为目标类创建代理类
     * */
    @Test
    public void test() {
        //1. 创建目标类
        final AdminService adminService = new AdminServiceImpl();

        //2. 创建代理对象
        /*
         * Proxy.newProxyInstance()  返回值为代理对象
         * classLoader : 类加载器(加载目标类--->读取目标类的信息)
         *        1. 当前线程类加载器   Thread.currentThread().getContextClassLoader()
         *        2. 当前类类加载       this.getClass().getClassLoader()
         *        3. 目标类类加载器     adminService.getClass().getClassLoader()
         * interfaces  : 实现的接口(和目标类实现同一个接口)
         *       {AdminService.class}
         *       adminService.getClass().getInterfaces()
         *
         * new InvocationHandler(): 代理对象调用方法时, 优先执行回调对象的invoke()
         * */
        ClassLoader classLoader = adminService.getClass().getClassLoader();
        Class[] interfaces = {AdminService.class};

        AdminService adminServiceProxy = (AdminService) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            // 相当于自己开发的静态代理中所写的代码(额外功能, 目标方法)
            /*
             * 参数1 proxy:  当前代理对象
             * 参数2 method: 当前代理对象调用方法的方法对象
             * 参数3 args:   当前代理对象调用方法的参数
             *
             * "方法名: "+method.getName()
             *"参数: "+args[0]
             * */
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //  额外的功能      调用目标方法
                /*
                 * 参数1: 执行哪个类中的方法
                 * 参数2: 执行哪个类中的方法携带的参数
                 * */
                Object invoke = null;
                try {
                    System.out.println("---开启事务---");
                    invoke = method.invoke(adminService, args);
                    System.out.println("---事务提交---");
                } catch (Exception e) {
                    System.out.println("---事务回滚---");
                    e.printStackTrace();
                }
                return invoke;
            }
        });
        String name = adminServiceProxy.find("张三");
        System.out.println(adminServiceProxy.getClass());//动态代理对象   class com.sun.proxy.$Proxy2

    }
}

service代码

package service;

public interface AdminService {
    public String find(String name);

    public void add();

    public void update();

    public void delete();
}

package service;

import dao.AdviceDaoImpl;

public class AdminServiceImpl implements AdminService {
    /*
     * 业务逻辑对象  负责处理业务逻辑, 调配用dao
     * 代理对象      完成事务控制
     *
     * */
    @Override
    public String find(String name) {
        System.out.println("调用dao find...");
        throw new RuntimeException("出现异常");
/*        return name;*/
    }

    @Override
    public void add() {
        System.out.println("调用dao add...");
    }

    @Override
    public void update() {
        System.out.println("调用dao update...");

    }

    @Override
    public void delete() {
        System.out.println("调用dao delete...");

    }

    public void setAdviceDao(AdviceDaoImpl adviceDao) {
    }
}

dao代码

package dao;

public interface AdviceDao {
    String find(String name);
    void add();
}
package dao;

public class AdviceDaoImpl implements AdviceDao {
    @Override
    public String find(String name) {
        System.out.println("通知dao-find");
        return null;
    }

    @Override
    public void add() {
        System.out.println("通知add-find");
    }
}

xml配置

    <!-- 管理业务逻辑对象(serviceImpl) -->
    <bean class="service.AdminServiceImpl" id="adminService"/>

    <!-- 管理代理对象 -->
    <bean class="proxy.AdminServiceImplProxy" id="adminServiceImplProxy">
        <property name="adminService" ref="adminService"/>
    </bean>

引入依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.26.RELEASE</version>
        </dependency>

创建动态代理的方式:jdk和cglib的区别

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值