SSM【Spring SpringMVC Mybatis】—— Spring(二)

news2025/1/18 8:46:45

如果对于Spring的一些基础理论感兴趣可见👇

SSM【Spring SpringMVC Mybatis】—— Spring(一)

目录

1、Spring中bean的作用域

1.1 语法

1.2 四个作用域

2、Spring中bean的生命周期

2.1 bean的生命周期

2.2 bean的后置处理器

2.3 添加后置处理器后bean的生命周期

3、Spring中自动装配【基于XML】

3.1 Spring中提供两种装配方式

3.2 Spring自动装配语法及规则

3.3 总结

4、Spring中注解【非常重要】

4.1 使用注解将对象装配到IOC容器中

4.2 使用注解装配对象中属性【自动装配】

自动装配(Autowired):

限定装配(Qualifier):

字面量数值装配(Value):

5、Spring完全注解开发【0配置】

5.1 完全注解开发步骤

5.2 示例代码

6、AOP前奏

6.1 代理模式

6.2 为什么需要代理【程序中】

6.3 手动实现动态代理环境搭建

6.4 手动实现动态代理关键步骤


1、Spring中bean的作用域

1.1 语法

在bean标签中添加属性:scope属性即可

<bean id="myBean" class="com.example.MyBean" scope="singleton"/>

1.2 四个作用域

  • singleton(默认值):单例模式,容器中只存在一个bean实例。

    • 对象创建时机:当创建Spring容器时,bean实例会被创建并放入容器中。
  • prototype:原型模式,每次获取bean时都会创建一个新的实例。

    • 对象创建时机:当调用getBean()方法获取bean实例时,每次都会创建一个新的实例。
  • request:请求作用域,每个HTTP请求都会创建一个新的bean实例。

    • 对象创建时机:每次HTTP请求到达时,都会创建一个新的bean实例,并在当前请求结束后销毁。
    • 当前请求:即URL不变的情况下,同一个HTTP请求中的所有处理都处于同一个请求域中。
  • session:会话作用域,每个HTTP会话都会创建一个新的bean实例。

    • 对象创建时机:在用户会话开始时创建一个bean实例,并在用户会话结束后销毁。
    • 当前会话:即用户在浏览器上不关闭、不更换的情况下持续访问应用的时间段。

2、Spring中bean的生命周期

2.1 bean的生命周期

  1. 通过构造器或工厂方法创建bean实例:Spring容器根据配置信息和依赖关系,使用构造器或工厂方法创建bean实例。

  2. 为bean的属性设置值和对其他bean的引用:Spring容器注入bean的属性值和依赖的其他bean。

  3. 调用bean的初始化方法:如果bean配置了初始化方法,Spring容器会在属性注入完成后调用该方法进行初始化。

  4. bean可以使用了:bean初始化完成后,可以被其他bean或应用程序代码引用和使用。

  5. 当容器关闭时,调用bean的销毁方法:如果bean配置了销毁方法,当Spring容器关闭时,会调用该方法进行清理工作。

2.2 bean的后置处理器

作用:在调用初始化方法前后对bean进行额外的处理。

实现:

实现BeanPostProcessor接口

重写方法

postProcessBeforeInitialization(Object, String):在bean的初始化方法调用之前调用,允许修改bean的属性值或做其他处理。

postProcessAfterInitialization(Object, String):在bean的初始化方法调用之后调用,允许在bean初始化完成后进行额外的处理。

注意:装配后置处理器会为当前容器中每个bean均装配,不能为局部bean装配后置处理器

2.3 添加后置处理器后bean的生命周期

① 通过构造器或工厂方法创建bean实例

② 为bean的属性设置值和对其他bean的引用

postProcessBeforeInitialization(Object, String):在bean的初始化之前执行

③ 调用bean的初始化方法

postProcessAfterInitialization(Object, String):在bean的初始化之后执行

④  bean可以使用了

⑤ 当容器关闭时,调用bean的销毁方法

3、Spring中自动装配【基于XML】

3.1 Spring中提供两种装配方式

手动装配:通过XML文件或Java配置显式地指定bean之间的依赖关系。

自动装配:让Spring容器根据一定的规则自动将合适的bean注入到目标bean中,而不需要显式地在配置文件中声明这些依赖关系。

3.2 Spring自动装配语法及规则

在bean标签中添加属性:Autowire即可,

常用的有两种:

  • byName:根据属性名称自动装配。Spring会查找与属性名相同的bean,并将其注入到目标bean的属性中。

  • byType:根据属性类型自动装配。Spring会查找与属性类型相同的bean,并将其注入到目标bean的属性中。如果找到多个匹配的bean,则会报错。

注意:基于XML方式的自动装配只能装配非字面量数值(即不是直接指定的常量值)。

3.3 总结

在基于XML的自动装配中,底层实际上是通过setter方法进行注入的。但通常不推荐使用byName和byType方式进行自动装配,因为它们可能会导致不可预期的结果,特别是在大型项目中容易出现问题。相反,建议使用注解方式进行自动装配。

4、Spring中注解【非常重要】

4.1 使用注解将对象装配到IOC容器中

约定:约束>配置【注解>XML】>代码

位置:在类上面标识

注意:

Spring本身不区分四个注解【四个注解本质是一样的@Component】,提供四个注解的目的只有一个:提高代码的可读性

在使用注解装配对象时,Spring会默认将类名的首字母小写作为bean的ID。你也可以使用value属性来指定bean的ID。

装配对象四个注解

@Component:装配普通组件到IOC容器

@Repository:装配持久化层组件到IOC容器

@Service:装配业务逻辑层组件到IOC容器

@Controller:装配控制层|表示层组件到IOC容器

使用注解步骤

导入相关jar包【已导入】

开启组件扫描

    <!--    开启组件扫描

            base-package:设置扫描注解包名【当前包及其子包】

    -->

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

使用注解标识组件

4.2 使用注解装配对象中属性【自动装配】

自动装配(Autowired):
  • 使用@Autowired注解可以实现对象属性的自动装配。
  • 装配原理基于反射机制,Spring会尝试按照byType进行匹配。
  • 如果匹配到一个对象,则正常使用。
  • 如果匹配不到对象,默认情况下会报错,但可以通过设置@Autowired(required=false)来避免报错。
  • 如果匹配到多个对象,会尝试按照byName进行唯一筛选,如果筛选失败则报错。
  • @Autowired注解的required属性可以设置为true或false,表示是否必须装配对象。

          /*expected at least 1 bean which qualifies as autowire candidate.   Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

          */
限定装配(Qualifier):

@Qualifier注解

作用:配合@Autowired一起使用,将设置beanId名称装配到属性中

注意:不能单独使用,需要与@Autowired一起使用

字面量数值装配(Value):

@Value注解

作用:装配对象中属性【字面量数值】

5、Spring完全注解开发【0配置】

5.1 完全注解开发步骤

5.1.1. 创建配置类

5.1.2. 在class上面添加注解

@Configuration:标识当前类是一个配置类,作用:代替XML配置文件

@ComponentScan:设置组件扫描当前包及其子包

5.1.3. 使用AnnotationConfigApplicationContext容器对象

5.2 示例代码

@Configuration

@ComponentScan(basePackages = "com.atguigu")

public class SpringConfig {

}

  @Test

    public void test0Xml(){

        //创建容器对象

//        ApplicationContext context =

//                new ClassPathXmlApplicationContext("applicationContext.xml");

        //使用AnnotationConfigApplicationContext容器对象

        ApplicationContext context =

                new AnnotationConfigApplicationContext(SpringConfig.class);

        DeptDaoImpl deptDao = context.getBean("deptDao", DeptDaoImpl.class);



        System.out.println("deptDao = " + deptDao);

    }

6、AOP前奏

6.1 代理模式

代理模式:我们需要做一件事情,又不期望自己亲力亲为,此时,可以找一个代理【中介】

我们【目标对象】与中介【代理对象】不能相互转换,因为是“兄弟”关系

  

6.2 为什么需要代理【程序中】

需求:实现【加减乘除】计算器类

在加减乘除方法中,添加日志功能【在计算之前,记录日志。在计算之后,显示结果。】

实现后发现问题如下

日志代码比较分散,可以提取日志类

日志代码比较混乱,日志代码【非核心业务代码】与加减乘除方法【核心业务代码】书写一处

总结:在核心业务代码中,需要添加日志功能,但不期望在核心业务代码中书写日志代码。

此时:使用代理模式解决问题【先将日志代码横向提取到日志类中,再动态织入回到业务代码中】

6.3 手动实现动态代理环境搭建

实现方式

基于接口实现动态代理: JDK动态代理

基于继承实现动态代理: Cglib、Javassist动态代理

实现动态代理关键步骤

 一个类:Proxy

概述:Proxy代理类的基类【类似Object】

作用:newProxyInstance():创建代理对象

一个接口:InvocationHandler

概述:实现【动态织入效果】关键接口

作用:invoke(),执行invoke()实现动态织入效果

6.4 手动实现动态代理关键步骤

注意:代理对象与实现类【目标对象】是“兄弟”关系,不能相互转换

创建类【为了实现创建代理对象工具类】

提供属性【目标对象:实现类】

提供方法【创建代理对象】

提供有参构造器【避免目标对为空】


package com.atguigu.beforeaop;



import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;





public class MyProxy {



    /**

     * 目标对象【目标客户】

     */

    private Object target;



    public MyProxy(Object target){

        this.target = target;

    }



    /**

     * 获取目标对象的,代理对象

     * @return

     */

    public Object getProxyObject(){

        Object proxyObj = null;



        /**

            类加载器【ClassLoader loader】,目标对象类加载器

            目标对象实现接口:Class<?>[] interfaces,目标对象实现所有接口

            InvocationHandler h

         */

        ClassLoader classLoader = target.getClass().getClassLoader();

        Class<?>[] interfaces = target.getClass().getInterfaces();

        //创建代理对象

        proxyObj = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {

            //执行invoke()实现动态织入效果

            @Override

            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                //获取方法名【目标对象】

                String methodName = method.getName();

                //执行目标方法之前,添加日志

                MyLogging.beforeMethod(methodName,args);

                //触发目标对象目标方法

                Object rs = method.invoke(target, args);

                //执行目标方法之后,添加日志

                MyLogging.afterMethod(methodName,rs);

                return rs;

            }

        });

        return proxyObj;

    }



//    class invocationImpl implements InvocationHandler{

//    }



}




@Test

    public void testBeforeAop(){



//        int add = calc.add(1, 2);

//        System.out.println("add = " + add);



        //目标对象

        Calc calc = new CalcImpl();

        //代理工具类

        MyProxy myProxy = new MyProxy(calc);

        //获取代理对象

        Calc calcProxy = (Calc)myProxy.getProxyObject();

        //测试

//        int add = calcProxy.add(1, 2);

        int div = calcProxy.div(2, 1);



    }













 

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

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

相关文章

【Vue】Vue指令与生命周期以及组件化编码

目录 常用内置指令v-text与v-htmlv-text : 更新元素的 textContentv-html : 更新元素的 innerHTML注意&#xff1a;v-html有安全性问题&#xff01;&#xff01;&#xff01;&#xff01; v-once与v-prev-oncev-pre ref与v-cloakrefv-cloak 自定义指令案例定义语法配置对象中常…

一键批量合并视频:掌握视频剪辑技巧解析,轻松创作完美影片

在数字时代的浪潮下&#xff0c;视频已成为人们记录和分享生活的重要工具。然而&#xff0c;对于许多非专业视频编辑者来说&#xff0c;将多个视频片段合并成一个完整的影片却是一项复杂且耗时的任务。幸运的是&#xff0c;云炫AI智剪一键批量合并视频功能的出现&#xff0c;让…

QT切换控件布局

1、切换前垂直布局 2、切换后水平布局 3、关键代码 qDebug() << "开始切换布局";QWidget *widget centralWidget();QLayout *layout widget->layout();if(layout){while(layout->count()){QLayoutItem *item layout->takeAt(0);if(item->layout…

自动化神器Autolt,让你不再重复工作!

随着互联网不断发展&#xff0c;它给我们带来便利的同时&#xff0c;也带来了枯燥、重复、机械的重复工作。今天&#xff0c;我要和大家分享一款老牌实用的自动化工具&#xff1a;AutoIt&#xff0c;它能够让你告别繁琐的重复性工作&#xff0c;提高工作效率。 这里透露一下&am…

C++中的complex

在 C 中&#xff0c;std::complex 是一个模板类&#xff0c;用于表示和操作复数。这个类是标准模板库&#xff08;STL&#xff09;的一部分&#xff0c;包含在 头文件中。std::complex 提供了一套丰富的功能&#xff0c;包括基本的算术运算、比较运算、数学函数等&#xff0c;使…

大语言模型LLM原理篇

大模型席卷全球&#xff0c;彷佛得模型者得天下。对于IT行业来说&#xff0c;以后可能没有各种软件了&#xff0c;只有各种各样的智体&#xff08;Agent&#xff09;调用各种各样的API。在这种大势下&#xff0c;笔者也阅读了很多大模型相关的资料&#xff0c;和很多新手一样&a…

苹果 iPhone 15 Pro Max 称霸:智能手机市场势不可挡

苹果 iPhone 15 Pro Max 称霸&#xff1a;智能手机市场势不可挡 概述 在拥挤且竞争激烈的智能手机市场中&#xff0c;苹果的 iPhone 15 Pro Max 成为明显的赢家&#xff0c;在 2024 年第一季度最畅销智能手机排行榜上名列前茅。根据 Counterpoint Research 的数据&#xff0c…

css: 动态设置网格线

参考这个博客做了网格线&#xff1a; http://t.csdnimg.cn/y20vM 把网格颜色&#xff0c;宽高和透明度做成可配置项。 <e-collapse title"网格线" :expand"false"><t-form-item label"颜色"><el-color-picker v-model"fo…

vue2+Ts中openLayer绘图工具组件封装

vue2Ts中openLayer绘图工具组件封装 效果&#xff1a; 封装组件代码&#xff1a; <!-- openLayer绘图工具 --> <template><a-button-group v-show"isShow"><a-button v-if"shouldShowButton(point)" click"draw(Point)"…

Axure10_win安装教程(安装、汉化、授权码,去弹窗)

1.下载Axure10 链接&#xff1a;https://pan.baidu.com/s/1fc8Bgyic8Ct__1IOv-afUg 提取码&#xff1a;9qew 2.安装Axure10 因为我的电脑是Windows操作系统&#xff0c;所以我下载的AxureRP-Setup-Beta v10.0.0.3816 (Win).exe 一直点下一步就行 3.Axure10中文 打开Axure…

(python)cryptography-安全的加密

前言 cryptography 是一个广泛使用的 Python 加密库&#xff0c;提供了各种加密、哈希和签名算法的实现。它支持多种加密算法&#xff0c;如 AES、RSA、ECC 等&#xff0c;以及哈希函数&#xff08;如 SHA-256、SHA-384 等&#xff09;和数字签名算法(如 DSA、ECDSA 等). 目录 …

Linux下Code_Aster源码编译安装及使用

目录 软件介绍 基本依赖 其它依赖 一、源码下载 二、解压缩 三、编译安装 四、算例运行 软件介绍 Code_aster为法国电力集团&#xff08;EDF&#xff09;自1989年起开始研发的通用结构和热力耦合有限元仿真软件。Code_aster可用于力学、热学和声学等物理现象的仿真分析&…

诺基亚3210复古风再起:情怀与现实的碰撞

在数字科技日新月异的今天&#xff0c;诺基亚的复古风潮却意外地掀起了波澜。这款曾经风靡一时的诺基亚3210&#xff0c;在时隔二十五年后&#xff0c;以全新的面貌再次回归市场&#xff0c;引发了无数人的怀旧与好奇。 诺基亚的这次“千禧回归”策略&#xff0c;无疑是对Y2K潮…

Java——类和对象第二节——封装

1.什么是封装 封装是面向对象程序的三大特性之一&#xff0c;面向对象程序的三大特性分别是封装&#xff0c;继承&#xff0c;多态 而封装简单来说就是套壳隐藏细节 打个比方&#xff1a; 在一些电脑厂商生产电脑时&#xff0c;仅对用户提供开关机键&#xff0c;键盘输入&a…

鸿蒙布局Column/Row/Stack

鸿蒙布局Column/Row/Stack 简介我们以Column为例进行讲解1. Column({space: 10}) 这里的space: 10&#xff0c;表示Column里面每个元素之间的间距为102. width(100%)&#xff0c;height(100%) 表示宽高占比3. backgroundColor(0xffeeeeee) 设置背景颜色4. padding({top: 50}) 设…

基于Springboot+Vue的Java项目-农产品直卖平台系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

【docker】SpringBoot应用容器镜像日志挂载

启动镜像时候使用 -v 挂载 首先得在宿主机创建目录&#xff1a;/workspace/java/demo/logs mkdir -pv /workspace/java/demo/logs 启动镜像 docker run -p 8080:8080 -itd -v /workspace/java/demo/logs/:/logs/ 192.168.2.1:5000/demo:0.0.1-SNAPSHOT -v /workspace/ja…

VMware虚拟机没有网,无法设置网络为桥接状态

今天需要使用Ubuntu18但现有虚拟机是Ubuntu20&#xff0c;由于硬盘空间不够大&#xff0c;所以删除了原来的虚拟机并重新搭建Ubuntu18的环境&#xff0c;然后发现虚拟机没有网络&#xff0c;而我之前的虚拟机这一切都是正常的。 在网络设置里勾选的是桥接模式但无法联网&#x…

如何基于可靠事件模式实现最终一致性?

今天我们一起来探讨一个分布式环境下的常见问题,这个问题与数据的一致性有关。那么,什么是数据一致性呢?要回答这个问题,需要我们回顾一下单块系统和分布式系统中对于数据处理的不同需求。 我们知道,传统的单块系统通常都只与一个数据库进行交互,所有的数据处理过程都位于…

前端连续发送同一个请求时,终止上一次请求

场景&#xff1a;几个tab页之间快速的切换&#xff08;tab页只是参数不同&#xff0c;下边的数据渲染给同一个data&#xff09;就会导致如果我在1,2,3&#xff0c;tab页按照顺序快速点击&#xff0c;发送三个请求&#xff0c;我想要展示的是3但是如果1或者2请求响应的时间比3长…