Spring-SpringFramework特性以及IOC相关知识

SpringFramework五大模块


特性

IOC思想和DI

IOC是容器,用于管理资源

IOC:Inversion of Control 反转控制

DI:Dependecy Injection 依赖注入 组件以预先定义好的方式接受来自容器的资源注入

IOC在Spring中的实现

spring提供两种方式:

1.BeanFactory

IOC容器的基本实现,是Spring内部使用的接口,面向spring本身

2.ApplicationContext

BeanFactory的子接口,提供更多高级特性,面向spring使用者
ApplicationContext的主要实现类:
ClassPathXmlApplicationContext :通过读取类路径下的XML格式的配置文件创建IOC容器对象

FileSystemXmlApplicaionContext:通过文件系统路径读取XML格式的配置文件创建IOC容器对象

Spring的入门案例

spring管理的对象为组件或bean

引入依赖

java 复制代码
 <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

创建spring的配置文件

创建spring的配置文件xml文件

自己获取IOC容器 通过类路径下的XML获取IOC

IOC可以有多个bean

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">
    <!--
    配置bean对象 将对象交给ioc容器管理
    id:bean的唯一标识,不能重复
    class:设置bean对象所对应的类型
     -->
    <bean id="helloworld" class="edu.npu.mwan.spring.pojo.HelloWorld"></bean>
</beans>

获取IOC容器中的bean

java 复制代码
public class HelloWorld {

    public void sayHello(){
        System.out.println("hello,s[ring");
    }

}
java 复制代码
public class Hello {
    @Test
    public void test(){
        ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
         //根据name获取bean 管理helloworld	
        HelloWorld helloWorld=(HelloWorld) ioc.getBean("helloworld");
        helloWorld.sayHello();
    }
}

IOC创建对象的方式

反射加工厂模式

什么是反射:在获取到 Class 对象之后,反向获取和操作对象的各种信息

IOC创建对象用的都是无参构造

获取bean的三种方式

方式一 :根据id获取

**方式二:**根据类型获取

java 复制代码
@Test
public void testHelloWorld(){
ApplicationContext ac = new
ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld bean = ac.getBean(HelloWorld.class);
bean.sayHello();
}

**方式三:**根据id和类型

java 复制代码
@Test
public void testHelloWorld(){
ApplicationContext ac = new
ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld bean = ac.getBean("helloworld", HelloWorld.class);
bean.sayHello();
}

④注意

当根据类型获取bean时,要求IOC容器中指定类型的bean有且只能有一个根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看:『对象 instanceof 指定的类型』的返回结果,只要返回的是true就可以认定为和类型匹配,能够获取到。

依赖注入

什么是依赖注入:

为bean的属性赋值
setter:配置bean时为属性赋值

java 复制代码
<bean id="studentOne" class="com.atguigu.spring.bean.Student">
<!-- property标签:通过组件类的setXxx()方法给组件对象设置属性 -->
<!-- name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关)
-->
<!-- value属性:指定属性值 -->
<property name="id" value="1001"></property>
<property name="name" value="张三"></property>
<property name="age" value="23"></property>
<property name="sex" value="男"></property>
</bean>

构造器注入:添加有参构造后在配置bean时

java 复制代码
<bean id="studentTwo" class="com.atguigu.spring.bean.Student">
<constructor-arg value="1002"></constructor-arg>
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="33"></constructor-arg>
<constructor-arg value="女"></constructor-arg>
</bean>

依赖注入的特殊值处理
字面量赋值

什么是字面量?即我们看到的数据本身

java 复制代码
<property name="name" value="张三"/>

此时张三是字面量
null值

java 复制代码
<property name="name">
<null />
</property>

错误写法

java 复制代码
<property name="name" value="null"></property>

xml实体

java 复制代码
<!-- 解决方案一:使用XML实体来代替 -->
<property name="expression" value="a &lt; b"/>
<!-- 解决方案二:使用CDATA节 -->
<!-- CDATA中的C代表Character,是文本、字符的含义,CDATA就表示纯文本数据 -->
<!-- XML解析器看到CDATA节就知道这里是纯文本,就不会当作XML标签或属性来解析 -->
<!-- 所以CDATA节中写什么符号都随意 -->
<value><![CDATA[a < b]]></value>

为类类型属性赋值

方式一:引用外部已声明的bean

java 复制代码
<bean id="clazzOne" class="com.atguigu.spring.bean.Clazz">
<property name="clazzId" value="1111"></property>
<property name="clazzName" value="财源滚滚班"></property>
</bean>
<bean id="studentFour" class="com.atguigu.spring.bean.Student">
<property name="id" value="1004"></property>
<property name="name" value="赵六"></property>
<property name="age" value="26"></property>
<property name="sex" value="女"></property>
<!-- ref属性:引用IOC容器中某个bean的id,将所对应的bean为属性赋值 -->
<property name="clazz" ref="clazzOne"></property>
</bean>

方式二:内部bean

java 复制代码
<bean id="studentFour" class="com.atguigu.spring.bean.Student">
<property name="id" value="1004"></property>
<property name="name" value="赵六"></property>
<property name="age" value="26"></property>
<property name="sex" value="女"></property>
<property name="clazz">
<!-- 在一个bean中再声明一个bean就是内部bean -->
<!-- 内部bean只能用于给属性赋值,不能在外部通过IOC容器获取,因此可以省略id属性 -->
<bean id="clazzInner" class="com.atguigu.spring.bean.Clazz">
<property name="clazzId" value="2222"></property>
<property name="clazzName" value="远大前程班"></property>
</bean>
</property>
</bean>

为数组类型属性赋值

java 复制代码
<property name="hobbies">
<array>
<value>抽烟</value>
<value>喝酒</value>
<value>烫头</value>
</array>
</property>

为集合类型属性赋值

为List集合类型属性赋值

java 复制代码
<property name="students">
<list>
<ref bean="studentOne"></ref>
<ref bean="studentTwo"></ref>
<ref bean="studentThree"></ref>
</list>
</property>

为Map集合类型属性赋值

java 复制代码
<property name="teacherMap">
<map>
<entry>
<key>
<value>10010</value>
</key>
<ref bean="teacherOne"></ref>
</entry>
<entry>
<key>
<value>10086</value>
</key>
<ref bean="teacherTwo"></ref>
</entry>
</map>
</property>

p命名空间

-ref表示实体类赋值

java 复制代码
<bean id="studentSix" class="com.atguigu.spring.bean.Student"
p:id="1006" p:name="小明" p:clazz-ref="clazzOne" p:teacherMapref="teacherMap"></bean>

bean的作用域

在Spring中可以通过配置bean标签的scope属性来指定bean的作用域范围

如果是在WebApplicationContext环境下还会有另外两个作用域

bean的生命周期

bean对象创建 (调用无参构造器)

给bean对象设置属性

bean对象初始化之前操作(由bean的后置处理器负责)
bean对象
初始化(需在配置bean时指定初始化方法)
bean对象
初始化之后操作
(由bean的后置处理器负责)

bean对象就绪 可以使用

bean对象销毁 (需在配置bean时指定销毁方法)
IOC容器关闭

自动装配

根据指定的策略,在IOC容器中匹配某一个bean,自动为指定的bean中所依赖的类类型或接口类

基于xml的自动装配

有一个UserController、UserService、UserServiceImpl作为UserService的实现类 UserDao UserDaoImpl
配置bean

使用bean标签的autowire属性设置自动装配效果
自动装配方式:byType

byType:根据类型匹配IOC容器中的某个兼容类型的bean,为属性自动赋值

若在IOC中,没有任何一个兼容类型的bean能够为属性赋值,则该属性不装配,即值为默认值

null

若在IOC中,有多个兼容类型的bean能够为属性赋值,则抛出异常

NoUniqueBeanDefinitionException

如果属性类型是userService则有对应类型的bean为其赋值,比如 userController中有userService

java 复制代码
<bean id="userController"
class="com.atguigu.autowire.xml.controller.UserController" autowire="byType">
</bean>
<bean id="userService"
class="com.atguigu.autowire.xml.service.impl.UserServiceImpl" autowire="byType">
</bean>
<bean id="userDao" class="com.atguigu.autowire.xml.dao.impl.UserDaoImpl"></bean>

byName

byName:将自动装配的属性的属性名,作为bean的id在IOC容器中匹配相对应的bean进行赋值

基于注解管理bean

注解

和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测

到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作。

本质上:所有一切的操作都是Java代码来完成的,XML和注解只是告诉框架中的Java代码如何执行。
扫描

pring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注

解进行后续操作。

Spring配置(applicationContext.xml)文件中可配置扫描范围

java 复制代码
<context:component-scan base-package="com.atguigu">
</context:component-scan>

组件所对应的bean的id

在我们使用XML方式管理bean的时候,每个bean都有一个唯一标识,便于在其他地方引用。现在使用

注解后,每个组件仍然应该有一个唯一标识。
默认情况

类名首字母小写就是bean的id。例如:UserController类对应的bean的id就是userController。
基于注解的自动装配
@Autowired注解

在成员变量上直接标记@Autowired注解即可完成自动装配,不需要提供setXxx()方法。以后我们在项

目中的正式用法就是这样。
@Autowired工作流程

注:先根据类型查找

相关推荐
木头没有瓜2 分钟前
ruoyi 请求参数类型不匹配,参数[giftId]要求类型为:‘java.lang.Long‘,但输入值为:‘orderGiftUnionList
android·java·okhttp
奋斗的老史2 分钟前
Spring Retry + Redis Watch实现高并发乐观锁
java·redis·spring
high20114 分钟前
【Java 基础】-- ArrayList 和 Linkedlist
java·开发语言
老马啸西风11 分钟前
NLP 中文拼写检测纠正论文 C-LLM Learn to CSC Errors Character by Character
java
Cosmoshhhyyy33 分钟前
LeetCode:3083. 字符串及其反转中是否存在同一子字符串(哈希 Java)
java·leetcode·哈希算法
AI人H哥会Java1 小时前
【Spring】基于XML的Spring容器配置——<bean>标签与属性解析
java·开发语言·spring boot·后端·架构
计算机学长felix1 小时前
基于SpringBoot的“大学生社团活动平台”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·后端
sin22011 小时前
springboot数据校验报错
spring boot·后端·python
开心工作室_kaic1 小时前
springboot493基于java的美食信息推荐系统的设计与实现(论文+源码)_kaic
java·开发语言·美食