spring基础知识详解
# 前言`目前大家应该都在用springboot,springclod了吧,(我也在用)。
不过感觉自己知识还很有残缺,所以又回来补一补spring的基础知识(蹲下来蓄力,准备提高自己)`
# 1 什么是spring
`sprin是一个对象管理容器,自动化完成对象创建,初始化,销毁等工作`
## spring的两个重要概念是AOP(切面编程)和IOC(容器,DI依赖注入)
1. 方便解耦,简化开发
2. AOP编程的支持
3. 声明式事务的支持
4. 方便程序的测试
5. 方便集成各种优秀框架
IOC是一种思想,一个概念,其实现方式多种多样。当前比较流行的实现方式是`DI`
IOC就是容器,以往的 被调用者(对象)都是有调用者来创建。而IOC内就是通过了第三方来创建管理bean的整个生命周期。调用者只需要告诉spring你需要什么类,这个类怎么创建即可。
我们目前都使用spring boot了,spring boot集成了spring,可以说是spring的改进版。但是最初的spring还是需要我们操作很多xml来告诉spring,我们要注入的对象是那个,以及如何注入。
>ApplicationContext.xml
>演示代码
```java
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
```
> 代码解释
```java
<beansbeans是xml文件的根节点
xmlns=http://www.springframework.org/schema/beans xmlns=xml NameSpace 类似于java中的package
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi是指xml文件遵守xml规范,xsi全名:xml schema instance
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 是指具体用到的schema资源
```
# 2 多配置文件
>演示代码 可以逗号分隔
```
new ClassPathXmlApplicationContext("applicationContext.xml","application-service.xml");
```
> 外部文件
```java
<import resource="application-service.xml"/>
```
# 3 Bean的定义与注册
`Spring的配置文件是用于指导Spring工厂进行Bean的生产、依赖关系注入及Bean实例分发的“图纸”,它是一个或多个标准的XML文档`
>演示代码
```java
<bean id="food" class="com.wanghaixin.Food"></bean>
```
`一个bean只能有一个id,但是可以有多个name作为别名`
> Alias 别名
```java
<alias name="user" alias="my_user_bean" />
```
# spring ioc container
> spring ioc container 管理一个或多个bean,bean来自xml中对bean定义的元数据(configuration metadata) 元数据信息
Class 类
Name,id 标识
Scope 作用域
Constructor arguments 构造器注入
Properties 属性注入
autowiring mode 自动装配
lazy-initialization mode 懒加载
initialization method 初始化
destruction method 销毁
# 构造器注入 constructor-arg
> Person的构造器
```java
public Person(String name, Integer age, Food food) {
super();
this.name = name;
this.age = age;
this.food = food;
}
```
> Xml指定name
```java
<bean id="person"class="com.wanghaixin.Person">
<constructor-arg name="age"value="18"></constructor-arg>
<constructor-arg name="name"value="zhangsan"></constructor-arg>
</bean>
```
> 指定类型
```java
<constructor-arg type="int" value="7500000"/>
```
> 指定index
```java
<constructor-arg index="0" value="7500000"/>
```
# 属性注入
```java
<bean id="person"class="com.wanghaixin.Person">
<property name="age"value="19"></property>
<property name="name"value="zhangsan"></property>
</bean>
```
> 使用p-namespace
属性注入
添加一个namespace
```java
xmlns:p=http://www.springframework.org/schema/p
```
> 使用 p
```java
<bean id="person" class="com.wanghaixin.Person"p:age="21" p:name = "zhangsan">
<bean id="person" class="com.wanghaixin.Person"p:age="21" p:name = "zhangsan" p:food-ref="food">
```
# depends-on 提前初始化
可以使某个bean在创建前,先创建别的bean
# lazy-init 懒加载
在容器启动后,bean被使用到的时候才加载。可以使用的lazy-init属性
```java
bean id="person" class="com.wanghaixin.Person" lazy-init="false"
```
> 作用域
>
spring为bean提供了6种作用域,其中4种只有在web-aware的ApplicationContext种才有用。用户也可以创建自定义的作用域。
singleton 、prototype 、websocket、request、session、application
>singleton scope 单例作用域
每一个类,在一个容器内只能产生一个实例
> prototype scope 原型作用域
该bean每次被注入,或者使用getBean()方法获取时,都返回一个新的实例。
> Request scope
>
该作用域的bean,在每个HTTP request都会新建一个实例,当一个request结束后,该实例也会被丢弃。
> Session scope
某一个用户在一段时间内,会使用同一个session,session有超时时间,过了超时时间则session失效。不同用户使用不同的session。
> Application scope
该作用域的bean,每一个application会创建一个
# MVC下Spring的单例
想在一个singleton内多次调用短存活时间的bean(propotype、request、session等),希望调用的是不同的实例,那么就需要使用AOP proxy技术
> 线程安全问题
>
业务对象并没有做线程的并发限制,因此不会出现各个线程之间的等待问题,或是死锁问题
MVC中的实体bean不是单例的
> 成员变量
在并发访问的时候这些成员变量将会是并发线程中的共享对象,也是影响线程安全的重要因素
> 引用类型的成员
其中引用类型的成员变量即我们在controller中注入的service,在service中注入的dao,这里将其定义为成员变量主
要是为了实例化进而调用里面的业务方法,在这些类中一般不会有全局变量,因此只要我们的业务方法不含有独立的
全局变量即使是被多线程共享,也是线程安全的。
Controller service dao 层中的业务类是多线程共享的,但是每个线程在处理数据的时候具体处理的数据是在每个线程中各自有一份。
> controller层
final类型 线程安全
成员变量 有状态数据有线程安全问题 不明觉厉,紫薯补丁 spring的id和name是同一个吗? 这里感觉Java后端比较少 我先收藏了 厉害了,先看看,学习一下 hobby 发表于 2022-11-21 20:18
spring的id和name是同一个吗?
不是哦 ,name可以有多个,但是id只能有一个。
页:
[1]