JDK动态代理(tedu)(内含源代码)

news2024/10/1 5:26:54

JDK动态代理(tedu)(内含源代码)

源代码下载链接地址:https://download.csdn.net/download/weixin_46411355/87546187

目录

  • JDK动态代理(tedu)(内含源代码)
  • `源代码下载链接地址:`[https://download.csdn.net/download/weixin_46411355/87546187](https://download.csdn.net/download/weixin_46411355/87546187)
    • 一、创建一个SpringBoot项目
    • 二、配置类
    • 三、service层
      • 3.1 接口类
      • 3.2 实现类
    • 四、JDK动态代理,根据目标类获取代理类的方法
    • 五、测试类
    • 六、测试结果
    • 问题:为什么 System.out.println(proxy);会打印事务开始和事务提交?

一、创建一个SpringBoot项目

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二、配置类

SpringConfig

package com.tedu.config;


import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@ComponentScan("com.tedu")
@Configuration
public class SpringConfig {

}

三、service层

3.1 接口类

UserService

package com.tedu.service;

public interface UserService {
    void addUser();
    void deleteUser();
}

3.2 实现类

package com.tedu.service;

import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService{

    @Override
    public void addUser() {
        System.out.println("完成用户新增");
    }

    @Override
    public void deleteUser() {
        System.out.println("完成用户删除");
    }
}

四、JDK动态代理,根据目标类获取代理类的方法

package com.tedu.proxy;

import com.sun.corba.se.spi.ior.ObjectKey;

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

public class JDKProxy {


    public static Object getProxy(Object target){
        //1.获取类加载器
        ClassLoader classLoader = target.getClass().getClassLoader();
        //2.获取接口
        Class<?>[] interfaces = target.getClass().getInterfaces();

        //通过代理的类新创建一个代理的对象
        return Proxy.newProxyInstance(classLoader, interfaces, getInvocationHandler(target));
    }

    //代理对象执行方法是调用
    public static InvocationHandler getInvocationHandler(Object target){
        //这些代码都是写死的
        return new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("======================事务开始=============================");
                //执行目标(真实对象的方法)
                Object result = method.invoke(target, args);
                System.out.println("==========================事务提交============================");
                return result;
            }
        };
    }


}

五、测试类

package com.tedu.test;

import com.tedu.config.SpringConfig;
import com.tedu.proxy.JDKProxy;
import com.tedu.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringTx {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = applicationContext.getBean(UserService.class);
        System.out.println(userService.getClass());

        UserService proxy = (UserService)JDKProxy.getProxy(userService);
        System.out.println(proxy.getClass());

        System.out.println(proxy);
        System.out.println(proxy.toString());

        //基于代理对象,执行业务操作 实现方法扩展
        proxy.addUser();
        proxy.deleteUser();
    }
}

六、测试结果

在这里插入图片描述

问题:为什么 System.out.println(proxy);会打印事务开始和事务提交?

因为System.out.println(proxy);默认等价于System.out.println(proxy.toString());虽然没有调用业务方法,但还是调用了目标对象的toString()方法,所以会出现事务开始和事务提交。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/398176.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue2学习笔记

文章目录1. 初识Vue2. 模板语法3. 数据绑定4. el与data的两种写法5. Vue中的MVVM6. 数据代理Object.defineProperty方法何为数据代理Vue中的数据代理7. 事件处理事件的基本使用事件修饰符键盘事件8. 计算属性姓名案例_插值语法实现姓名案例_methods实现姓名案例_计算属性实现姓…

dp-过河卒

题目描述 如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的 C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。 例如上图

【HashMap】| 深度剥析Java SE 源码合集Ⅱ | 你会吗?

目录一. &#x1f981; HashMap介绍1.1 特点1.2 底层实现二. &#x1f981; 结构以及对应方法分析2.1 结构组成2.1.1 成员变量2.1.2 存储元素的节点类型2.1.2.1 链表Node类2.1.2.2 树节点类2.1.2.3 继承关系2.2 方法实现2.2.1 HashMap的数组初始化2.2.2 计算hash值2.2.3 添加元…

HTML URL

HTML 统一资源定位器 (Uniform Resource Locators) URL 是一个网页地址。 URL 可以由字母组成&#xff0c;如 "w3cschool.cn"&#xff0c;或互联网协议&#xff08;IP&#xff09;地址&#xff1a; 120.79.88.157。大多数人进入网站使用网站域名来访问&#xff0c;因…

主流的“对象转换工具”使用示例大全以及性能的对比

目录 前言 源码地址 代码示例 引入依赖 先定两个实体用于转换 定义一个接口让所有转换器都集成 Apache BeanUtils BeanCopier bean-mapping bean-mapping-asm Dozer 自己写get/set JMapper json2json MapStruct&#xff08;推荐&#xff09; ModelMapper OriK…

使用Vue实现数据可视化大屏功能(二)

引入数据大屏相关组件 用Datav插件做大屏可视化的组件&#xff0c;官网地址 http://datav.jiaminghi.com/ &#xff0c;整个组件库都是基于Vue React版本实现&#xff0c;主要用于构建大屏数据可视化页面&#xff0c;具有很多种类的组件可以使用。其安装方式如下。 npm instal…

WebRTC中的NAT穿透

NAT简介 我们知道&#xff0c;WebRTC会按照内网、P2P、中转的顺序来尝试连接。在大部分的情况下&#xff0c;实际是使用P2P或者中转的。这里P2P的场景主要使用的技术就是NAT穿透。 我们先简单了解下NAT。NAT在真实网络中是常见的&#xff0c;它的出现一是为了解决ipv4地址不够…

2.1操作系统-进程管理:进程的同步与互斥、信号量与PV操作、PV操作与互斥模型、PV操作与同步模型

2.1操作系统-进程管理&#xff1a;进程的同步与互斥、信号量与PV操作、PV操作与互斥模型、PV操作与同步模型进程的同步与互斥PV操作PV操作与互斥模型PV操作与同步模型进程的同步与互斥 进程是动态的&#xff0c;有一些动态变迁的过程&#xff0c;进程在计算机中是可以同时存在…

JavaEE简单示例——Spring框架的简单介绍

简单介绍&#xff1a; 在我们之前创建的Java项目中&#xff0c;会发现我们的各种类&#xff0c;接口文件和配置文件都放在了一起&#xff0c;虽然我们也做了一些包管理去管理我们的这些文件&#xff0c;但是对于我们来说&#xff0c;这些操作还是太繁琐了&#xff0c;尤其是当…

Spark-RDD创建、并行分区

集合&#xff08;内存&#xff09;中创建 RDD 外部存储&#xff08;文件&#xff09;创建 RDD 并行与分区 分区的设定 集合&#xff08;内存&#xff09;中创建 RDD 从集合中创建 RDD&#xff0c;Spark 主要提供了两个方法&#xff1a;parallelize 和 makeRDD&#xff0c;从…

【源码解析】SpringBoot缓存之@Cacheable的快速入门和源码解析

快速入门 启动类上添加注解EnableCaching在方法上添加注解Cacheable。 OverrideCacheable(cacheNames "value", key "#code_#dictKey")public String getValue(String code, Integer dictKey) {return baseMapper.getValue(code, dictKey);}OverrideCac…

数据结构和算法学习记录——线性表之单链表(上)-初始单链表及其头插函数(顺序表缺陷、单链表优点、链表打印)

单链表的概念单链表是一种链式存取的数据结构&#xff0c;链表中的数据是以结点来表示的。每个结点的构成&#xff1a;元素(数据元素的映象) 指针(指示后继元素存储位置)。元素就是存储数据的存储单元&#xff0c;指针就是连接每个结点的地址数据。以“结点的序列”表示的线性…

Kubernetes Service简介

Service 之前我们了解了Pod的基本用法&#xff0c;我们也了解到Pod的生命是有限的&#xff0c;死亡过后不会复活了。我们后面学习到的RC和Deployment可以用来动态的创建和销毁Pod。尽管每个Pod都有自己的IP地址&#xff0c;但是如果Pod重新启动了的话那么他的IP很有可能也就变…

cocos2dx+lua学习笔记:事件派发器CCEventDispatcher

前言 本篇在讲什么 cocos2dx内关于事件监听和派发的调度器EventDispatcher相关内容 本篇适合什么 适合初学Cocos2dx的小白 适合想要学习EventDispatcher的新手 本篇需要什么 对Lua语法有简单认知 对C语法有简单认知 对Cocos2dx有简单认知 Cocos2dx-Lua的开发环境 依…

【Spring事物三千问】DataSource的设计和常用实现——Hikari、Druid

javax.sql.DataSource javax.sql.DataSource 是 jdk 提供的接口&#xff0c;各个连接池厂商 和 Spring 都对 DataSource 进行了设计和实现。 javax.sql.DataSource 是连接到物理数据源的工厂接口。它是 java.sql.DriverManager 功能的替代者&#xff0c;是获取数据库连接的首选…

H5视频付费点播打赏影视系统程序全开源运营版,含完整的前后台+数据库

源码介绍&#xff1a; 这是一个非常棒的精品代码&#xff0c;之前官方网站售价可是超过2w的。我拿过来了简单测试了一下&#xff0c;完美。好久没有遇到这么好的代码了&#xff0c;特此整理了一份完整的搭建教程并分享一下。 thinkphp开发&#xff0c;前后端分离设计&#xf…

Vue3做出B站【bilibili】 Vue3+TypeScript+ant-design-vue【快速入门一篇文章精通系列(一)前端项目案例】

本项目分为二部分 1、后台管理系统&#xff08;用户管理&#xff0c;角色管理&#xff0c;视频管理等&#xff09; 2、客户端&#xff08;登录注册、发布视频&#xff09; Vue3做出B站【bilibili】 Vue3TypeScriptant-design-vue【快速入门一篇文章精通系列&#xff08;一&…

ASEMI高压MOS管20N60参数,20N60尺寸,20N60体积

编辑-Z ASEMI高压MOS管20N60参数&#xff1a; 型号&#xff1a;20N60 漏极-源极电压&#xff08;VDS&#xff09;&#xff1a;600V 栅源电压&#xff08;VGS&#xff09;&#xff1a;30V 漏极电流&#xff08;ID&#xff09;&#xff1a;20A 功耗&#xff08;PD&#xff…

项目最后一刻发生范围变更该怎么处理?

不管是项目需求发生了变化&#xff0c;还是第一轮可交付成果没有完全达到预期&#xff0c;在项目范围定义的初始阶段之后可能发生变化的原因有很多。当这种情况发生时&#xff0c;你需要准备好一个计划来处理最后一刻的范围变更和调整。 什么是范围变更&#xff1f; 范围变更是…

浪潮 KaiwuDB x 山东重工 | 打造离散制造业 IIoT 标杆解决方案

近日&#xff0c;浪潮 KaiwuDB 携手山东重工集团有限公司&#xff08;以下简称&#xff1a;山东重工&#xff09;重磅发布“离散制造业 IIoT 解决方案”。该 IIoT 方案以 KaiwuDB 就地运算专利技术为底座&#xff0c;搭建了”多快优智”的“13N”方案体系&#xff0c;目前已率先…