Spring6笔记

动力节点B站Spring6学习笔记——Spring的入门程序 根据B站动力节点老杜讲的Spring6教程整理了学习笔记,分享给大家,共同学习进步~这套Spring教程基于Spring6讲解,Spring6是下一个十年的新开端。 阅读详情

这里写一些关于学习spring中值得记录的知识点,之前直接学了项目那里入手的springboot,现在看回spring,才会知道原来是怎样运行的

关于sping中如何完成自动注入

springboot中我们可以直接@AutoWired注解去实现自动注入,但是在spring中,我们通过xml配置实现自动注入。
这里我们不需要再去一个个把bean写出来,只需要在controller,service,写相应的下一层类型属性,如controller中写service类型,并且写上其set方法,直接调用相应的方法,具体如下

public class UserController {

    private UserService userService;

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void addUser(){
        System.out.println("controller方法执行了..");
        /*UserService userService = new UserServiceImpl();
        userService.addUserService();*/

        //调用service方法
        userService.addUserService();
    }
}
<bean id="userController" class="com.ljx.spring6.iocxml.auto.controller.UserController"
          autowire="byType">

    </bean>
    <bean id="userService" class="com.ljx.spring6.iocxml.auto.service.UserServiceImpl"
          autowire="byType">

    </bean>
    <bean id="userDao" class="com.ljx.spring6.iocxml.auto.dao.UserDaoImpl">

    </bean>

spring会从属性中找到对应xml上配置的bean,这时候会根据你标签autowired去选择对应自动装配的方法

基于注解管理bean

开启组件扫描

要想实现注解开发,spring最基本功能之一,为了不用再去xml文件中配置创建bean,我们要先开启组件扫描
基本操作是:在xml配置文件中填入

<context:component-scan base-package="com.ljx.spring6"></context:component-scan>

base-package是要扫描的包及其子包,开启后我们就可以在class上加入注解(@Compoent,@Controller,@Repository,@Service),之后我们就可以在测试类中直接获取bean了

@Autowired和@Qualifier联合注入

@Autowired注解注入的方法有好几种,最常见的属性注入,还有创建属性set方法的set注入,构造方法注入,构造方法形参注入,还有只有一个构造函数可以不用注解隐性注入。
除此之外还有一个比较特殊,需要用到两个注解
打个比方,当我们dao层接口有两个实现类,正常使用autowired是无法注入的,两个bean冲突,所以我们需要在上qualifier value值为对应bean名字,就可以实现对应bean注入,不会冲突

手写Ioc

手写创建bean

原理分析

对于spring来说,Ioc绝对是其核心中的核心,管理bean,创建bean,bean的生命周期全都围绕着Ioc容器,那我们要想自己手写Ioc,就必须要先理解其原理。
首先第一点,我们要创建的对象如何交给Ioc容器管理?前面我们用注解开发就需要加上@Compoent告诉Ioc我们要让他管理bean了,所以我们需要在需要管理的bean中自定义注解@Bean,并且让spring扫描注解对应的包,我们就可以实现该功能了。接着我们要获取bean,在之前,我们是通过创建BeanFactory子类ApplicationContext,并通过getbean方法来获取bean的,所以我们还要自己写一个ApplicationContext,并定义方法,返回我们需要的bean对象。还有,我们每次想要获取bean,总不可能每次都要new一个context吧?还需要完成自动注入吧?所以我们还需要创建一个注解来定义属性注入吧。

步骤

综上分析,我们需要的步骤如下:
1、创建子模块
2、创建测试类 service dao
3、创建两个注解 @Di @Bean
4、创建bean容器接口 ApplicationContext定义方法,返回对象
5、实现bean容器接口
(1)返回对象
(2)根据包规则加载bean 扫描com.ljx及其子包所有类,看是否有@Bean注解,如果有,通过反射实例化

手写属性注入

首先,我们要先了解属性注入在原先是怎么实现的,需要满足什么条件。第一点,我们在注入属性时需要加入@Autowired代表我们要注入,这个属性一般是一个对象。
因此我们需要创建一个注解,这个注解标记让我们知道哪些属性是要注入的。前面我们已经完成bean的创建,接着我们只需要在beanFactory的map集合中获取键值对,
再遍历获取值(就是我们的对象),接着再通过反射获取到对象的属性。随后我们便可依次遍历看看哪些属性上有注解,有的话我们就从beanFactory中找出对应类型属性的对象(service,dao) 赋值给 通过反射获取到的属性。
这样我们属性赋值就完成了

开发日志

遇到的问题

我在一直用push到github时,电脑崩溃蓝屏,我再次打开项目想要push时弹出0 file committed, 81 files failed to commit: 手写Ioc,bean的创建 cannot lock ref ‘HEAD’: unable to resolve reference ‘refs/heads/master’: reference broken
gpt反应这是cannot lock ref ‘HEAD’: unable to resolve reference ‘refs/heads/master’: reference broken,这通常是由于 Git 仓库的 HEAD 或 refs/heads/master 引用损坏导致的。
看来是因为.git文件损坏导致无法上传,github给的解决方法非常复杂。我再解决完问题后总结最方便的方法。
首先,确保github上代码已经更新,然后我们删掉原来这个项目,在新的目录里(创建新的项目)用终端打开,用git重新克隆

git clone "+github仓库http链接"

这样我们就可以从远端仓库同步到新的项目里,如果不确定远端仓库是否安全,可以先克隆,如果没有问题,就可以直接删除旧项目。或者可以check一下,这里我还没有试过

补充

我们在push后如果想要撤销,可以revert,这里撤销的是本地的仓库,我们在idea终端里直接强制push,就可以覆盖掉远程仓库。但是这样很容易有风险,建议先备份好数据。不然很容易文件丢失

关于代理

代理在java基础中也有学过,但是就像反射一样,代理在Spring中也尤为重要,特别是AOP的实现。
前面关于代理的知识还是比较抽象,我们从简单例子实现,现在我们有一个Calculator接口,里面有加减乘除抽象方法。

public interface Calculator {

    int add(int i,int j);

    int sub(int i,int j);

    int mul(int i,int j);

    int div(int i,int j);
}

然后我们设立一个实现类用于完成方法最基础的功能

public class CalculatorImpl implements Calculator{
    @Override
    public int add(int i, int j) {

        int result = i + j;
        System.out.println("方法内部 result=" + result);
        return result;
    }

    @Override
    public int sub(int i, int j) {
        int result = i - j;
        System.out.println("方法内部 result=" + result);
        return result;
    }

    @Override
    public int mul(int i, int j) {
        int result = i * j;
        System.out.println("方法内部 result=" + result);
        return result;
    }

    @Override
    public int div(int i, int j) {
        int result = i / j;
        System.out.println("方法内部 result=" + result);
        return result;
    }
}

好了,现在我想要完成在这些方法基础上再加入日志功能,方法执行前和执行后我们都要执行,我们应该如何实现呢?
其实无需修改实现类中方法的代码,实在是过于麻烦,我们在原有基础上加入代理类即可。
首先我们要弄清楚,原来的功能我们不能舍弃,是不是让另一个类来实现我们现在的功能,顺便把扩展功能(日志)也实现。这里我直接引用动态代理
想要获得我们想要的代理对象,第一步,是不是应该传入我们原来实现类的对象,在代理类中通过构造器传入变量。接着我们设计一个方法,用于返回代理对象
其中核心是Proxy.newProxyInstance(classLoader,interfaces,invocationHandler),姑且理解为JDK已经帮我们实现动态代理的方法了,封装起来,我们直接使用即可
三个参数分别对应1 ClassLoader:加载动态生成代理类的类加载器。
2 Class<?>[] interface:目标对象实现的所有接口的class类型数组。
3 InvocationHandler:设置代理对象实现目标对象方法的过程。
这里主要是invocationHandler,我们需要重写其中invoke方法,这里面包括我们基础功能和扩展功能,最后返回结果就可以了

public class ProxyFactory {

    //目标对象
    private Object target;

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

    //返回代理对象
    public Object getProxy(){
        /*
        Proxy.newProxyInstance()方法
        有三个参数
        1 ClassLoader:加载动态生成代理类的类加载器
        2 Class<?>[] interface:目标对象实现的所有接口的class类型数组
        3 InvocationHandler:设置代理对象实现目标对象方法的过程
        * */

        //1 ClassLoader:加载动态生成代理类的类加载器
        ClassLoader classLoader = target.getClass().getClassLoader();

        //2 Class<?>[] interface:目标对象实现的所有接口的class类型数组
        Class<?>[] interfaces = target.getClass().getInterfaces();

        //3 InvocationHandler:设置代理对象实现目标对象方法的过程
        InvocationHandler invocationHandler = new InvocationHandler() {

            //1 代理对象
            //2 需要重写目标对象方法
            //3 method方法里面参数
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //方法调用前执行
                System.out.println("[动态代理][日志]" + method.getName()+"参数:"+ Arrays.toString(args));
                //调用目标方法
                Object result = method.invoke(target, args);
                //方法调用后执行
                System.out.println("[动态代理][日志]" + method.getName()+"结果:"+ result);
                return result;
            }
        };
        return Proxy.newProxyInstance(classLoader,interfaces,invocationHandler);

    }
}

别急,是不是还有很多问题

为什么 JDK 动态代理必须基于接口?

JDK 动态代理的原理:
Proxy.newProxyInstance() 方法会在运行时动态创建一个代理类,该类实现了目标对象的所有接口。
由于 Java 语言的设计 不允许动态继承具体类,但 允许实现接口,所以 JDK 代理要求 目标对象必须实现接口。
当我们调用 new ProxyFactory(new CalculatorImpl()).getProxy(); 时:
JDK 代理会动态创建一个 新的类,该类实现了 Calculator 接口。
代理对象实际上是这个新类的实例,它并不是 CalculatorImpl 的实例,而是 实现了相同接口的一个代理对象。

方法是在invoke实现的,然后才返回代理对象,我们是如何通过代理对象调用invoke的?

JDK 动态代理调用 invoke 的过程
当你通过 代理对象 调用方法时,比如:

javaCalculator proxy = (Calculator) new ProxyFactory(new CalculatorImpl()).getProxy();
proxy.add(3, 5);

其执行过程如下:
代理对象接收 add(3, 5) 方法调用(实际上调用的是 JDK 生成的动态代理类)。
代理对象的 add 方法内部会调用 InvocationHandler.invoke() 方法。
在 invoke() 方法内部:
先执行前置增强逻辑(打印日志)。
通过 method.invoke(target, args) 反射调用目标对象的方法。
记录日志,返回结果。
最终返回计算结果 3 + 5 = 8。

总结就是:
代理对象是 JDK 生成的类,它实现了 Calculator 接口,但方法内部并没有真正执行 add() 逻辑,而是调用 InvocationHandler.invoke() 方法。
Proxy.newProxyInstance() 会在运行时生成 $Proxy0 代理类,该类的 add() 方法内部直接调用 h.invoke()。
h.invoke() 方法执行 日志增强逻辑 + 反射调用目标对象方法,最终返回方法结果。

动力节点B站Spring6学习笔记——Spring对IoC的实现 根据B站动力节点老杜讲的Spring6教程整理了学习笔记,分享给大家,共同学习进步~ 这套Spring教程基于Spring6讲解,Spring6是下一个十年的新开端。 四、Spring对IoC的实现 4.1 IoC 控制反转 控制反转是一种思想。 控制反转是为了降低程序耦合度,提高程序扩展力,达到OCP原则,达到DIP原则。 控制反转,反转的是什么? 将对象的创建权利交出去,交给第三方容器负责。 将对象和对象之间关系的维护权交出去,交给第三方容器负责。 控制反转这种思想如何实现呢? DI(Depe 阅读详情

相关推荐

UnityWebGL异常捕获全攻略:从报错提示到完美解决的3种配置方案

本文详细解析了UnityWebGL项目中异常捕获的三种核心配置方案:禁用异常、仅捕获显式异常以及完全捕获异常(无堆栈跟踪)。通过对比不同方案在构建体积、运行性能及错误信息详细度上的差异,帮助开发者根据开发、测试与发布阶段的不同需求,选择并配置最优的异常处理策略,从而有效提升WebGL应用的调试效率和线上稳定性。

5f4d3s2a1q的博客 399

cglib动态代理和jdk动态代理的区别与应用

 1,引入如果从一个Controller调用Service的非事务方法a,然后在a里调用事务方法b,b事务生效吗? public void update() { updateActual(); int a = 1 / 0; } @Transactional public void updateActual() { WithHo...

一个想写小说的程序员 4万+

Qcom camera hal简介

Qcom camera hal简介

weixin_42136255的博客 7770

Spring6学习及复习笔记

个人使用,不断维护

qq_74924951的博客 1410

吃透 AM32 无人机电调:从源码架构到工作原理的全方位解析(附实践指南)(中)

介绍了三相电机控制中的SVPWM算法实现及保护机制设计。SVPWM部分详细解析了电压矢量扇区判断、占空比计算和过调制保护,通过限制占空比范围(0-100%)防止电机失控,并提供了完整的代码实现。保护模块则重点分析了过流、过压/欠压、过温三种保护机制,采用分级处理策略(硬保护停机/软保护降功率)确保系统安全。此外,文章还介绍了参数管理模块在STM32 Flash中的存储方案,包括参数定义、数据结构和读写操作,为电机控制系统提供了完整的解决方案。

bother3000的博客 1389

Spring AI + RAG 构建电商智能客服:从 PDF 文档解析到精准问答的全链路实战

核心框架:向量数据库:- PostgreSQL + pgvector (生产推荐)- Redis Stack (轻量级方案)- ChromaDB (快速原型)文档解析:- Apache PDFBox: PDF 文本提取- Spring AI Document Readers: 结构化解析大模型:- 阿里云百炼 (DashScope)- 本地部署:Qwen/ChatGLM/*** 电商领域实体*/@Data@Builder@ToString/*** 商品类型。

一起修行,不孤单。这里有编程语言、开发工具、学习方法论和踩坑笔记。用简单的话说复杂的事,陪你从小白到进阶。周更干货,欢迎一起成长! 381

【亲测免费】 动力节点老杜Spring6 配套笔记PDF文件

动力节点老杜Spring6 配套笔记PDF文件 【下载地址】动力节点老杜Spring6配套笔记PDF文件 - **文件名称**: 动力节点老杜Spring6 配套笔记PDF文件- **文件格式**: PDF- **内容概述**: 该笔记源自动力节点老杜的Spring6课程,详细记录了课程中的重要知识点和实践案例,帮助学习...

gitblog_06627的博客 617

Chatbox使用指南

Chatbox使用指南

weixin_65289420的博客 2万+

spring6笔记

spring6笔记:从0到1搭建环境,IOC、DI、AOP,基于XML和注解的全面讲解,以及基于反射手写实现IOC、DI。其他技术:单元测试、事务、Resources资源操作、i18n国际化、数据校验等。

m0_67061805的博客 1861

【Kingbase人大金仓】授权文件更换

本文介绍了金仓数据库授权文件更换的步骤:1.通过ksql或客户端工具查询数据库版本;2.在官网下载对应版本的license.bat文件;3.替换前先备份原授权文件(使用tar命令压缩),再用新文件覆盖原文件。注意事项包括:版本号需严格对应,授权文件通常位于安装目录下,可使用find命令查找具体位置。操作需谨慎,建议先备份原文件以便恢复。

qq_34463511的博客 3467

使用单片机开发PWM的案例&相关项目源码

该项目使用STM32单片机生成PWM信号,通过改变PWM的占空比来控制连接在PWM输出引脚(如PA0)上的LED的亮度。在主循环中,通过改变比较值,PWM信号的占空比在0%到100%之间变化,从而实现LED亮度的渐变效果。这个项目是一个基础的PWM控制示例,通过学习和实践这个项目,可以掌握PWM的基本原理和使用方法,并为进一步开发和应用打下良好的基础。该项目实现了使用STM32单片机产生PWM信号,并通过改变PWM的占空比来控制LED的亮度。配置PWM输出引脚(如PA0),确保其模式为PWM输出。

清风明月 643

[记录学习]自学动力节点老杜Spring6笔记_01

动力节点老杜Spring6自学笔记

sls1223074612的博客 3702

R语言实战:从Raw Counts到TPM/FPKM的完整转换指南(含代码调试技巧)

本文详细介绍了在R语言环境中将RNA-seq原始计数(raw counts)转换为TPM/FPKM值的完整流程,包含代码实现和常见错误调试技巧。通过具体案例演示如何正确处理基因长度和测序深度因素,实现表达量标准化,为生物信息学分析提供可靠数据基础。特别适合需要进行转录组数据分析的研究人员和实验室技术人员参考。

weixin_28559803的博客 481

Spring6学习笔记7:国际化 i18n

本文是尚硅谷Spring6教程中国际化i18n的学习笔记。包括i18n概述、Java国际化、Spring6国际化等内容。供个人学习使用。

专注Java和MySQL领域知识分享 1241

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

spring6 笔记(3 万字详解)

尚硅谷spring笔记带你一套掌握spring

2301_79083000的博客 1523

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Spring6 框架笔记

AOP 是一种设计思想,是软件设计领域中的面向切面编程。利用AOP可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各个部分之间的耦合度降低,提高程序的可重用性,同时提高开发的效率。JIT(just in time)动态编译(实时),边运行边编译。优点:在程序运行的时候,动态生成代码。缺点:启动比较慢,编译的时候需要占用运行时资源AOT(ahead of time)提前编译优点:可以把源代码直接转换成机器码,启动快,内存占用低缺点:运行的时候不能优化,程序安装时间过长。

m0_63237640的博客 2108

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

spring6-笔记

Spring 是一款主流的 Java EE 轻量级开源框架 ,Spring 由“Spring 之父”Rod Johnson 提出并创立,其目的是用于简化 Java 企业级应用的开发难度和开发周期。Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring 框架除了自己提供功能外,还提供整合其他技术和框架的能力。Spring 自诞生以来备受青睐,一直被广大开发人员作为 Java 企业级应用程序开发的首选。时至今日,Spring 俨然

AllenIverrui的博客 840

Spring6学习笔记

手写spring6代码地址 spring官网地址 spring重点笔记 Spring和SpringMVC的区别

weixin_43761434的博客 496

Spring6 笔记

Spring6学习笔记

LiruiVsXueSheng的博客 394

动力节点B站Spring6学习笔记——第二章Spring概述

来自百度百科Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。Spring最初的出现是为了解决EJB臃肿的设计,以及难以测试等问题。Spring为简化开发而生,让程序员只需关注核心业务的实现,尽可能的不再关注非业务逻辑代码(事务控制,安全日志等)。

2301_76637757的博客 190

Spring6基础笔记

Spring 是一款主流的 Java EE 轻量级开源框架 ,Spring 由“Spring 之父”Rod Johnson 提出并创立,其目的是用于简化 Java 企业级应用的开发难度和开发周期。Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring 框架除了自己提供功能外,还提供整合其他技术和框架的能力。Spring 自诞生以来备受青睐,一直被广大开发人员作为 Java 企业级应用程序开发的首选。时至今日,Spring 俨然

质胜文则野,文胜质则史。文质彬彬,然后君子。 1412

spring6学习笔记

Spring框架核心概念与实践 摘要:Spring是一个主流的JavaEE轻量级开源框架,旨在简化企业级应用开发。其核心包括IoC(控制反转)和AOP(面向切面编程)两大特性。IoC容器通过依赖注入管理对象生命周期,AOP则实现非侵入式的功能增强。Spring 6要求JDK 17+环境,配置文件支持XML方式定义Bean。开发流程包括:配置依赖(spring-context)、创建Bean类、编写XML配置文件、通过ApplicationContext获取Bean实例。日志框架推荐使用Log4j2,通过配置

qq_58956810的博客 941
上一篇: 手写Ioc
下一篇: 关于动态代理
KAI_KD
博客等级 码龄4年 125粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值