Spring配置相关

news/2024/10/15 6:13:27

Spring

  • Spring技术是JavaEE开发必备技能,企业开发技术选型命中率>90%
  • 专业角度
    • 简化开发:降低企业级开发的复杂性
    • 框架整合:高效整合其他技术,提高企业级应用开发与运行效率

初识Spring

了解Spring家族

  • Spring官网:https://spring.io/
  • Spring发展到今天已经形成了一种开发的生态圈,Spring提供了若干个项目,每个项目用于完成特定的功能
  • 重点学习
    • Spring Framework
    • Spring Boot
    • Spring Cloud

Spring Framework

Spring Framework系统架构

  • SpringFramework是Spring生态圈中最基础的项目,是其他项目的根基

Spring Framework系统架构图:

image.png

核心概念

  • IoC/DI
  • IoC(InversionofControl)控制反转
    • 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
  • Spring技术对Ioc思想进行了实现
    • Spring提供了一个容器,称为Ioc容器,用来充当Ioc思想中的"外部
    • Ioc容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在Ioc容器中统称为Bean
  • DI(DependencyInjection)依赖注入
    • 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
  • 目的:充分解耦
    • 使用Ioc容器管理bean(IoC)
    • 在Ioc容器内将有依赖关系的bean进行关系绑定(DI)

IoC入门

1、利用Maven导入Spring的坐标 spring-context

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

2、创建配置文件:在 resources 目录下创建 applicationContext.xml 文件。

3、配置bean

# bean标签标识配置bean
# id属性表示bean的名字
# class属性表示bean的定义类型<bean id="" class=""></bean># 注意:bean定义时id属性在同一个上下文中不能重复

4、获取Ioc容器

public static void main(String args[]){//获取IoC容器//ApplicationContext是一个接口,我们new一个它的实现对象//参数是我们的配置文件ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");//获取bean//xml文件下配置bean的id名BookService bs =  ctx.getBean("bookService");//这时候就获取到Ioc容器中bean的对象了
}

DI入门

  1. 基于Ioc管理bean
  2. 通过配置进行依赖注入
<bean id="Dao" class="com.fyislo.dao.impl.Dao"/><bean id="Service" class="com.fyislo.service.impl.Service"># property标签表示配置当前bean的属性# name属性表示我们配给谁?(属性名称)# ref属性表示我们要把谁给对方(bean的id属性)<property name="dao" ref="Dao"/>
</bean>

Bean

Bean的配置

使用 name 属性,可以给bean配置多个别名。多个别名之间可以用逗号,分号,空格分隔。

<bean id="Dao" class="com.fyislo.dao.impl.Dao"/># name属性可以给bean配置多个别名。多个别名之间可以用逗号,分号,空格分隔。
<bean id="Service" name="service service2" class="com.fyislo.service.impl.Service"><property name="dao" ref="Dao"/>
</bean>

注:获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常 NoSuchBeanDefinitionExceptionNoSuchBeanDefinitionException: Nobeannamed'bookServiceImpl'available

bean的作用范围

Spring给我们创建的bean默认是单例的。

如果需要非单例的bean,则需要在配置文件 <bean> 的标签中添加一个属性: scope

  • scoper
    • singleton:单例(默认)
    • prototype:非单例
<bean id="Service" name="service service2" class="com.fyislo.service.impl.Service" scope="prototype"><property name="dao" ref="Dao"/>
</bean>
  • 适合交给容器进行管理的bean
    • 表现层对象
    • 业务层对象
    • 数据层对象
    • 工具对象
  • 不适合交给容器进行管理的bean
    • 封装实体类的域对象

bean的实例化

1、使用构造方法完成创建bean(无参构造)

  • bean本质上就是对象
  • 无参构造如果不存在,将抛出异常 BeanCreationException

2、通过静态工厂创建bean(了解)

通过 class 属性告诉工厂类,在通过factory-method属性告诉Spring工厂里面的哪个方法是造对象的。

<bean id="orderDao" class="factory.OrderDaoFactory" factory-method="getorderDad"/>

3、实例工厂创建bean

  1. 先配置工厂的bean
  2. 通过 factory-bean 指定实例工厂的bean
  3. 通过 factory-method 指定造对象的方法
<bean id="userFactory" class="factory.UserDaoFactory"/><bean id="orderDao" factory-method="getuserDao" factory-bean="userFactory"/>

4、使用 FactoryBean<T> 实例化

实现接口中的两个方法。

public class UserDaoFactoryBean implements FactoryBean<UserDao>{//代替原始实例工厂中创建对象的方法//得到bean的实例public UserDao getobject() throws Exception{return new UserDaoImpl();}//得到bean的类型public Class<?> getobjectType(){//返回创建对象的字节码文件return UserDao.class;}//设置该bean是单例还是非单例的//默认可以不写该方法public boolean isSingleton(){//返回true:单例//返回false:非单例return true;}
}

这时候配置就很简便了

<bean id="userDao" class="factory.UserDaoFactoryBean"/>

bean的生命周期

  • 生命周期:从创建到消亡的完整过程
  • bean生命周期:bean从创建到销毁的整体过程
  • bean生命周期控制:在bean创建后到销毁前做一些事情

<bean>标签中init-method 属性可以指定一个方法,在bean创建前运行一个方法。

<bean> 标签中 destroy-method 属性可以指定一个方法,在bean销毁前运行的一个方法。

<bean id="" class="" init-method="init" destroy-method="destory"/>

关闭容器

public static void main(String args[]){//获取IoC容器//ApplicationContext是一个接口,但是它没有close()方法。//ClassPathXmlApplicationContext是它的实现类,有close()方法。ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");//方法一:直接关闭容器ctx.close();//方法二:注册关闭钩子,在任何时间注册都可以。//作用:在虚拟机退出之前,把容器关完了再退出ctx.registerShutdownHook();
}

使用Spring接口来控制生命周期(这样便不用去xml文件中指定控制生命周期的方法)

实现 InitializingBeanDisposableBean 两个接口

public class Service implements InitializingBean, DisposableBean{public void afterPropertiesSet() throws Exception{//设置属性之后执行该方法}public void destroy() throws Exception{//}
}

Bean在初始化过程中经历的阶段

  • 初始化容器
    1. 创建对象(内存分配)
    2. 执行构造方法
    3. 执行属性注入(set方法)
    4. 执行bean初始化方法
  • 使用bean
    1. 执行业务操作
  • 关闭/销毁容器
    1. 执行bean销毁方法

bean销毁时机

  • 容器关闭前出发bean的销毁
  • 关闭容器方式:
    • 手动关闭容器
      • ConfigurableApplicationContext接口close()操作
    • 注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机
      • ConfigurableApplicationContext接口registerShutdownHook()操作

bean相关属性

image.png

依赖注入

  • 依赖注入的两种方式
    • 普通方法(set方法)
    • 构造方法
  • 依赖注入的两种类型
    • 引用类型
    • 简单类型(基本数据类型和String)
  • 依赖注入方式
    • setter注入
      • 简单类型
      • 引用类型
    • 构造器注入
      • 简单类型
      • 引用类型

setter方式注入

1、setter方式注入引用类型,在DI入门已有提过。

在xml文件中配置 <bean> 标签,并在其中配置 <property> 标签即可

2、setter方式注入简单类型

<bean id="Service" class="com.fyislo.service.impl.Service"># property标签表示配置当前bean的属性# name属性表示我们配给谁?(属性名称)# 只需要把ref属性替换成value属性,即可完成简单类型的注入<property name="int" value="123"/><property name="string" value="name"/>
</bean>

构造器注入

1、构造器注入引用类型

将setter注入的set方法更换为有参构造即可,在xml的配置有所改变,如下:

<bean id="Service" class="com.fyislo.service.impl.Service"># 只需把property标签更换为constructor-arg标签即可<constructor-arg name="形参的名称1" ref=""/><constructor-arg name="形参的名称2" ref=""/>
</bean>

2、构造器注入简单类型

# 标准写法:有指定形参的名称
<bean id="Service" class="com.fyislo.service.impl.Service"># 只需把constructor-arg标签的ref更换为value即可<constructor-arg name="形参的名称1" value=""/><constructor-arg name="形参的名称2" value=""/>
</bean>
# 解决形参名称耦合的问题
<bean id="Service" class="com.fyislo.service.impl.Service"># 不使用name指定形参名称,使用type指定形参类型<constructor-arg type="int" value=""/><constructor-arg type="java.lang.String" value=""/>
</bean>
# 解决参数类型重复问题,使用位置解决参数匹配
<bean id="Service" class="com.fyislo.service.impl.Service"># 使用index指定参数位置<constructor-arg index="0" value=""/><constructor-arg index="1" value=""/>
</bean>

依赖注入方式选择

  1. 制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
  2. .可选依赖使用setter注入进行,灵活性强
  3. Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
  4. 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
  5. 实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
  6. 自己开发的模块推荐使用setter注入

依赖自动装配

  • IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
  • 自动装配的方式
    • 按类型(常用)
    • 按名称
    • 按构造方法
    • 不启用自动装配

前提:想要自动装配,要提供set方法,xml配置文件如下:

  • autowire可选值
    • byType:按类型
    • byName:按名称
# 自动装配,使用aotuwire属性
# 该类型的bean对象在配置文件中必须是唯一的
# 不唯一,它怎么知道给你注入哪一个?
<bean id="" class="" autowire="byType"/>
  • 依赖自动装配特征
    • 自动装配用于引用类型依赖注入,不能对简单类型进行操作
    • 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
    • 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
    • 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效

集合注入

<bean id="" class=""><property name="array"><array><value>100</value><value>30</value><ref bean="beanId"/> # 引用类型</array></property><property name="list"><list><value>adjkl</value><value>30</value></list></property><property name="list"><set><value>adjkl</value><value>30</value></set></property><property name="list"><map><entry key="name" value="zhangsan"/><entry key="" value=""/></map></property><property name="properties"><props><prop key="key">value</prop><prop key="key">value</prop></props></property>
</bean>

加载properties文件

  1. 开启context命名空间
  2. 使用context空间加载properties文件(加载的文件从resources目录中寻找)
  3. 使用属性占位符:${}读取properties文件中的属性
<?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"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,把两行末尾的beans更换为contexthttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  # 1.开启context命名空间2.使用context空间加载properties文件(加载的文件从resources目录中寻找)# 3. 使用属性占位符:${}读取properties文件中的属性<context:property-placeholder location="resources目录下的properties文件"/><bean id="service" class="com.fyislo.service.Impl.BookServiecImpl"><property name="url" value="${jdbc.url}"/><property name="user" value="${jdbc.user}"/>  </bean>  
</beans>

加载properties文件

image.png

依赖注入相关

image.png

容器

创建容器

1、加载类路径下的配置文件

//加载类路径下的配置文件
ApplicationContext act =  new ClassPathXmlApplicationContext("applicationContext.xml");

2、从文件系统下加载配置文件

//从文件系统下加载配置文件
ApplicationContext act = new FileSystemXmlApplicationContext("C:\software\project\JavaProject\JavaStudy\src\main\resources\applicationContext.xml");

加载bean的方式

# 根据名称获取bean,需要强转
BookService bookService = (BookService) act.getBean("service");# 根据名称获取bean,不需要强转
BookService bookService = act.getBean("service",BookService.class);# 根据类型获取bean
BookService bookService = act.getBean(BookService.class);# 加载多个配置文件
ApplicationContext act =  new ClassPathXmlApplicationContext("bean1.xml","bean2.xml");

ApplicationContext 的顶层接口是 BeanFactory ,它也可以创建IoC容器,但存在局限性。

  • ApplicationContextBeanFactory 的区别
    • 它们加载bean的时机不同
      • ApplicationContext 是启动容器后立即加载
      • BeanFactory 是延迟加载

如果需要 ApplicationContext 完成延时加载,可以给 bean 标签添加一个属性 lazy-init="true"

image.png

免责声明:此片文章是个人学习笔记,存在借鉴,若有冒犯或侵权,联系可删除。

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

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

相关文章

M3位带地址映射

01. 位带概述位带操作简单的说,就是把每个比特膨胀为一个 32 位的字,当访问这些字的时候就达到了访问比特的目的,比如说 GPIO 的 ODR 寄存器有 32 个位,那么可以映射到 32 个地址上,我们去访问这 32 个地址就达到访问 32 个比特的目的。这样我们往某个地址写 1 就达到往对…

aardio封装库) 微软开源的js引擎(ChakraCore)

前言 做爬虫肯定少不了JavaScript引擎的使用,比如在Python中现在一般用pyexecjs2来执行JavaScript代码,另外还有一些其他执行JavaScript的库:https://github.com/eight04/node_vm2: rpc调用nodejs,需要安装node https://github.com/eight04/deno_vm: rpc调用deno,需要安装…

shell编程

!/bin/bash set -u -e 安全 export 环境变量 cat /porc/$PID/export 位置变量 $0: 表示脚本或命令本身的名称。 $1, $2, $3, ...: 表示第一个、第二个、第三个等参数的值。 $* 或 $@: 表示所有位置参数的列表。 $#: 表示传递给脚本或命令的位置参数的个数。 echo $[12^4] =8 …

python雨滴谱删除不需要的粒径列值

粒径的取值范围为:0.31~8mm 因此excel中标记红色的都需要删除: txt文件为(红框为留下来的数据),一共五组数,也就是五个时间的数: 那么我只留下我需要的d的n的数据,删除不需要的列:# -*- coding:utf-8 -*- """ @author: su @file: deletlie.py @time: 2…

[题解]P4597 序列 sequence

P4597 序列 sequence 是CF13C Sequence的加强版,\(N\leq 5*10^5\)。 如果想了解\(O(N^2)\)的DP解法请看此文。给定\(N\)个数,每次操作可以选其中一个数\(+1\)或\(-1\)。请问要让这个数列不降,最少需要多少次操作? 看到数据范围发现不能用\(O(N^2)\)的dp了,需要换一种思路。…

关于雨滴谱数据的处理

粒径的取值范围为:0.31~8mm 因此excel中标记红色的都需要删除: txt文件为(红框为留下来的数据),一共五组数,也就是五个时间的数: 那么我只留下我需要的d的n的数据,删除不需要的列:# -*- coding:utf-8 -*- """ @author: su @file: deletlie.py @time: 2…

1.验整码的发送与检验

通过restTemplate.exchage()来发送验证码,需要4个参数,url,请求方式,请求内容,需要相应类型) 响应的结果为map结合,我们需要取出key值,用俩次map取值可以取出key 检验验证 需要输入验证码和key restTeMPLATE.exhcange(url,....);//发送请求获得验证码 请求内容为空 判断…

如何在本地局域网中通过SMB协议加密共享文件

Windows网络发现共享是Windows操作系统中的一个功能,通过该功能,用户可以在局域网内自动发现和访问其他计算机上共享的资源,如文件夹、打印机等。这个功能通常使用SMB(Server Message Block)协议来实现文件共享和网络资源访问。V1.0 于2024年5月1日发布于博客园序言Window…