Spring基础知识学习总结(四)

news2024/9/22 13:36:06

(5)Spring新注解

使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:

  • 非自定义的Bean的配置:<bean>
  • 加载properties文件的配置:<context:property-placeholder>
  • 组件扫描的配置:<context:component-scan>
  • 引入其他文件:<import>

即创建配置类,替代xml配置文件

@Configuration //用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解
@ComponentScan
//用于指定 Spring 在初始化容器时要扫描的包。
//作用和在 Spring 的 xml 配置文件中的context:component-scan base-package="com"/>一样
@Bean //使用在方法上,标注将该方法的返回值存储到 Spring 容器中
@PropertySource //用于加载.properties 文件中的配置
@Import //用于导入其他配置类

 (6) 完全注解开发测试

原始xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
">
<!--    <bean id="accountDao" class="com.hhh.Dao.Impl.AccountDaoImpl"></bean>-->

<!--    <bean id="accountService" class="com.hhh.Service.Impl.AccountServiceImpl">-->
<!--        <property name="accountDao" ref="accountDao"/>-->
<!--    </bean>-->

<!--    组件扫描:Spring容器会扫描这个包里所有类,从类的注解信息中获取Bean的信息-->
    <context:component-scan base-package="com.hhh"></context:component-scan>

<!--    加载外部的properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="root"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

 

1> 新建一个核心配置类:SpringConfiguration,相当于总配置

package com.hhh.common;

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

@Configuration
//声明当前类是一个配置类
@ComponentScan("com.hhh")
//开启包扫描 相当于xml中的<context:component-scan base-package="com.hhh"/>
@Import({DataSourceConfiguration.class})
//导入其他配置类
//@Import({DataSourceConfiguration.class}) 里面的值其实是一个数组,可以加载多个类,如:@Import({DataSourceConfiguration1.class,DataSourceConfiguration2.class})
public class SpringConfiguration {
}

2> 新建数据源配置类:DataSourceConfiguration,相当于分配置

package com.hhh.common;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

@PropertySource("classpath:jdbc.properties")
//加载外部配置文件相当于<context:property-placeholder location="classpath:jdbc.properties"/>
public class DataSourceConfiguration {
    @Value("${jdbc.driver}")
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    @Bean("dataSource") //Spring会将当前方法的返回值以指定名称存到Spring容器当中
    public DataSource getDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

3> 测试加载核心配置类创建Spring容器

package com.hhh.Controller;

import com.hhh.Service.AccountService;
import com.hhh.common.SpringConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class AccountController {
    public static void main(String[] args) {
//        ApplicationContext app = new ClassPathXmlApplicationContext("note.xml");
//        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("note.xml");
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        AccountService accountService = app.getBean(AccountService.class);
        accountService.save();
//        app.close();
    }
}

4> 测试结果

 

 

最终pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>spring_temp</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>6.0.13</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.33</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
        <version>6.0.13</version>
    </dependency>
    <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>javax.annotation-api</artifactId>
      <version>1.3.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>6.0.13</version>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.30</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.assertj</groupId>
      <artifactId>assertj-core</artifactId>
      <version>3.24.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

c. bean的生命周期

1.  定义

对于普通的 Java 对象,当 new 的时候创建对象,然后该对象就能够使用了。一旦该对象不再被使用,则由 Java 自动进行垃圾回收。

而 Spring 中的对象是 bean,bean 和普通的 Java 对象没啥大的区别,只不过 Spring 不再自己去 new 对象了,而是由 IoC 容器去帮助我们实例化对象并且管理它,我们需要哪个对象,去问 IoC 容器要即可。IoC 其实就是解决对象之间的耦合问题,Spring Bean 的生命周期完全由容器控制。

2. 周期过程 

(1)通过构造器创建 bean 实例(无参数构造)
(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
(3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
(4)调用 bean 的初始化的方法(需要进行配置初始化的方法)
(5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization
(6)bean 可以使用了(对象获取到了)
(7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

 

 

以下是对您提出的问题的详细深入讲解:

(1)通过构造器创建bean实例(无参数构造)

在Spring中,通过无参数构造器创建bean实例是最常见的方式之一。当Spring容器启动时,它会查找指定类的无参数构造器,并使用反射机制来创建bean的实例。这种方式要求bean的类必须有一个可访问的无参数构造器。

配置方式

在Spring的XML配置文件中,通过<bean>标签的class属性指定bean的全限定类名(包名+类名),Spring会自动查找并使用该类的无参数构造器来创建bean实例。

<bean id="myBean" class="com.example.MyBeanClass"/>

(2)为bean的属性设置值和对其他bean引用(调用set方法)

Spring支持通过setter方法为bean的属性设置值,并且可以引用容器中的其他bean。这通过<property>标签在<bean>标签内部进行配置。

配置方式

  1. 设置基本类型和String类型的属性值

    <bean id="myBean" class="com.example.MyBeanClass">
    <property name="propertyName" value="propertyValue"/>
    </bean>
  2. 引用其他bean

    <bean id="anotherBean" class="com.example.AnotherBeanClass"/>
    <bean id="myBean" class="com.example.MyBeanClass">
    <property name="anotherBean" ref="anotherBean"/>
    </bean>

这里,MyBeanClass类中需要有setPropertyNamesetAnotherBean这两个setter方法。

(3)把bean实例传递bean后置处理器的方法postProcessBeforeInitialization

Bean后置处理器(BeanPostProcessor)是Spring框架中一种特殊的bean,用于在bean的初始化前后进行额外的处理。postProcessBeforeInitialization方法在bean的初始化方法(如配置的init-method)被调用之前执行。

配置方式

  1. 实现BeanPostProcessor接口

    public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 对bean进行自定义处理
    return bean; // 必须返回bean实例,以便继续后续的初始化流程
    }
    }
  2. 将BeanPostProcessor注册到Spring容器中

    <bean class="com.example.MyBeanPostProcessor"/>

(4)调用bean的初始化的方法(需要进行配置初始化的方法)

Spring允许通过配置文件指定bean的初始化方法,该方法会在bean的所有属性被设置之后调用。

配置方式

<bean>标签中使用init-method属性指定初始化方法。

<bean id="myBean" class="com.example.MyBeanClass" init-method="initMethod"/>

这里,MyBeanClass类中需要有initMethod这个无参数方法。

(5)把bean实例传递bean后置处理器的方法postProcessAfterInitialization

postProcessAfterInitialization方法在bean的初始化方法(如配置的init-method)被调用之后执行。它同样是在BeanPostProcessor接口中定义的。

执行时机

该方法的执行时机紧跟在bean的初始化方法之后,允许在bean完全初始化之后进行额外的处理。

(6)bean可以使用了(对象获取到了)

在Spring容器完成bean的创建、属性设置、初始化等流程后,bean就处于可用状态,可以通过ApplicationContextgetBean方法获取bean的实例。

获取方式

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBeanClass myBean = context.getBean("myBean", MyBeanClass.class);

(7)当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)

Spring允许通过配置文件指定bean的销毁方法,该方法会在容器关闭时被调用,用于执行清理工作。

配置方式

<bean>标签中使用destroy-method属性指定销毁方法。

<bean id="myBean" class="com.example.MyBeanClass" destroy-method="destroyMethod"/>

这里,MyBeanClass类中需要有destroyMethod这个无参数方法。

ps: bean生命周期的图引用了Spring Bean的生命周期(一图流+详细说明)_spring bean 生命周期图-CSDN博客

                                                       ❤️❤️❤️IOC完结撒花❤️❤️❤️

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

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

相关文章

Linux 文件、重定向、缓冲区

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a; Linux 目录 一、文件 1、文件的理解&#xff08;浅层&#xff09; 1.文件是什么&#xff1f; 2.文件操作的前提 3.文件的存储 4.一个进程可以打开多个文件吗&#xff1f;如果可以怎么管理的&#xf…

【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式

文章目录 webView使用步骤示例 HttpURLConnection使用步骤示例GET请求POST请求 okHttp使用步骤1. 添加依赖2. 创建OkHttpClient实例3. 创建Request对象构建请求4. 发送请求5. 获取响应 Pull解析方式1. 准备XML数据2. 创建数据类3. 使用Pull解析器解析XML webView WebView 是 An…

三大浏览器Google Chrome、Edge、Firefox内存占用对比

问题 Chrome、Edg、Firefox三家究竟谁的占用少 结论 打开一个页面内存占用 Firefox>Edge>Chrome 打开打量页面内存占用 Firefox>Chrome>Edge 从监视器可以看到Edge增加一个页面增加一个页面不到100M而其它浏览器需要150M左右;Firefox浏览器主线程内存占用800M比…

Java之TCP网络编程

TCP网络编程 1 概述 在TCP通信协议下&#xff0c;计算机网络中不同设备上的应用程序之间可以通信&#xff0c;通信时需严格区分客户端&#xff08;Client&#xff09;与服务器端&#xff08;Server&#xff09;。 在Java中&#xff0c;对于这样基于TCP协议下连接通信的客户端…

数据结构-常见排序的七大排序

1.排序的概念及其运用 1.1排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录…

Arkose 验证码:网络抓取工具的最佳实践

网络爬虫已经成为企业和开发人员最常用的工具&#xff0c;用于有效地从网络中收集数据。当然&#xff0c;大家都会遇到的最常见挑战是大量的 CAPTCHA 出现&#xff0c;这会使工作流程陷入停滞。其中&#xff0c;Arkose Labs Captcha&#xff08;称为 Funcaptcha&#xff09;以其…

探索N卡录制:游戏录屏工具会是网页录屏的最佳伴侣吗?

在这个数字时代&#xff0c;无论是游戏玩家、教育工作者还是内容创作者&#xff0c;高质量的录屏工具都是必不可少的。NVIDIA显卡&#xff08;简称N卡&#xff09;以其卓越的图形处理能力而闻名&#xff0c;而N卡录制功能则进一步扩展了其应用范围&#xff0c;特别是在游戏录屏…

【SpringBoot 属性加载机制】

SpringBoot 属性加载 一个 SpringBoot 应用的配置属性可以有多种不同的来源, 比如可以来自操作系统的环境变量, 比如可以来自 application.yaml 文件; 每一种不同的属性来源, 都会被 SpringBoot 封装成一个PropertySource对象, 保存在 Environment 对象的 PropertySources 类型…

proteus仿真c51单片机(三)多定时任务的编程——时分秒发生器

实验步骤 1、打开PROTEUS软件选取元件&#xff0c;连线绘制电路图。 2、打开KEIL软件编制程序进行调试、编译。 3、将编译的HEX代码装入PROTEUS软件绘制的电路图的单片机中。 4、仿真运行观察实验现象&#xff0c;若与要求的实验现象不同&#xff0c;检查程序和电路图找…

Linux目录结构常用命令和文件管理解析

一.Linux目录结构 bin:binary二进制&#xff0c;普通用户执行命令都在这里 boot:和计算机启动的相关文件都放这 dev:device设备、驱动、硬件 etc:配置文件也叫控制台文件 home:来装用户自己的文件的&#xff0c;普通用户的家目录主目录&#xff0c;每个普通用户进来都有自…

PythonStudio 控件使用常用方式(十二)TMaskEdit

PythonStudio是一个极强的开发Python的IDE工具&#xff0c;它使用的是Delphi的控件&#xff0c;常用的内容是与Delphi一致的。但是相关文档并一定完整。现在我试试能否逐步把它的控件常用用法写一点点&#xff0c;也作为PythonStudio的参考。 从1.2.1版开始&#xff0c;Python…

Android compose OutlinedTextField 输入框设置固定高度后,内容挤压显示不全

原因&#xff1a; decorationBox里边contentPadding() 默认为16.dp internal val TextFieldPadding 16.dp 修改方法1&#xff1a; copy OutlinedTextField.kt 源码&#xff0c;decorationBox的contentPadding参数开放出来 /*** author 创建人&#xff1a;蒙石瑞* date …

【大模型从入门到精通11】openAI API 提示链的力量2

这里写目录标题 提示链的力量&#xff1a;阅读和处理JSON字符串基于产品信息生成用户响应综合性的客户服务互动结论理论问题 提示链的力量&#xff1a;阅读和处理JSON字符串 当处理复杂的工作流程时&#xff0c;通常会以JSON格式传递数据。以下示例演示了如何将JSON字符串转换…

【Linux QT】添加Json-C库

前言 在Linux应用开发中&#xff0c;Linux设备和服务器通信时&#xff0c;两者之间数据的传输通常采用JSON数据格式来作为载体&#xff0c;便于两者之间的数据交互。当设备端接收到服务端下发的JSON数据&#xff0c;设备端需要对JSON格式的数据进行解析&#xff1b;当设备端需要…

Java设计模式(命令模式)

定义 将一个请求封装为一个对象&#xff0c;从而让你可以用不同的请求对客户进行参数化&#xff0c;对请求排队或者记录请求日志&#xff0c;以及支持可撤销的操作。 角色 抽象命令类&#xff08;Command&#xff09;&#xff1a;声明用于执行请求的execute方法&#xff0c;通…

CSS实现hover时文本上下出现线条

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>复杂Hover效果示例</title><style>p {f…

【案例38】Can’t get connection from database 排查详细记录

问题现象 客户要搭建灰度环境&#xff0c;启动后&#xff0c;登录超级管理员报连接不上数据库的错误。 Can’t get connection from database(XXX) 问题分析 1、一般碰到这个问题&#xff0c;初步就开始怀疑是sysconfig数据源不通导致的。 发现数据源是通的。 2、在sysconf…

【案例40】Apache中mod_proxy模块的使用

NC中间件 应用场景&#xff1a;配置了apache的情况&#xff0c;包括uap集群&#xff0c;配置https等场景下均适用&#xff1b;如果是单机&#xff08;NC单结点情况不存在问题&#xff0c;则不用配置这项; was环境也不用配置此项。&#xff09; 解决方案&#xff1a;按如下两…

【15.PIE-Engine案例——加载Landsat 8 SR数据集】

加载Landsat 8 SR数据集 原始路径 欢迎大家登录航天宏图官网查看本案例原始来源 最终结果 具体代码 /*** File : Landsat8SRImages* Time : 2020/7/21* Author : piesat* Version : 1.0* Contact : 400-890-0662* License : (C)Copyright 航天宏图信息技…

【C++】BFS解决Floodfill问题

目录 Floodfill算法介绍 解决方法 BFS 图画渲染 算法思路&#xff1a; 代码实现&#xff1a; 岛屿数量 算法思路 代码实现 岛屿的最大面积 算法思想 代码实现 被围绕的区域 算法思路 代码实现 总结&#xff1a; Floodfill算法介绍 Floodfill翻译过来就是“洪…