Spring原理 —— IOC容器注解版

Spring5 框架

概述

轻量级来源框架
解决企业应用开发的复杂性
核心部分: IOC AOP
IOC 创建对象的过程交给Spring
AOP 面向切面编程

特点

方便解耦,简化开发,创建对象和调用对象的过程分开
AOP支持
方便程序的测试
方便集成各种优秀框架
降低J2EE API的使用难度
方便的事务操作

IOC

Spring创建bean的方式

在xml文件中设置bean的class(全路径名)和id(名称)
然后用ClassPathXmlApplication读取配置文件,然后即为创建了一个Spring的上下文(容器)
然后用context对象的getBean方法根据id和class拿到容器中的对象
这就是最原始的Spring使用方法

创建bean也基于注解来创建bean

如果我们自己在调用方法的时候创建对象,那么在程序运行过程中就会创建很多对象会耗费很多性能,而这些对象我们只是调用它的方法,并没有对它进行修改,因而这种对象在全局只需要一个,所以我们可以为这些类创建一个单例对象,把它放到一个map里面,我要用的时候直接从map里面拿就可以了。而我们自己创建单例对象时,如果这个对象要引用其他对象而其他对象并且这个对象在单例池中没有,我们就需要提前创建依赖对象,确定它在内存中的位置,然后把它的引用赋值给当前创建的对象的引用里面,而为了保证依赖的对象也是单例的,我们要把这个对象放到另一个map里面,也就是二级缓存,等我们创建这个对象时就判断二级缓存,如果有就把他拿出来完善后续的创建过程,这样才能保证创建的对象都是单例的。创建好后把引用放入map里面,然后去创建其他对象。创建对象前还要判断单例池中有没有,防止重复创建。如果我们自己创建单例对象,就要为所有类都编写上述代码,工作量就很大,而Spring就帮我们将上述过程已经了封装,当我们需要一个单例对象时,只需要加上注解,Spring就能帮助我们创建出来,减少了我们的代码量。

使用工厂模式,将创建对象的过程交给工厂,从而降低创建对象的过程和调用对象的过程的耦合度

创建bean xml解析,反射,工厂模式

IOC 容器底层就是对象工厂
IOC容器实现的两种方式:(两个接口)
BeanFactory Spring内部使用,顶级接口,加载配置文件时不会创建对象,使用时才去创建(懒加载)

ApplicationContext BeanFactory的子接口,提供给开发人员使用。加载配置文件时就会创建对象(立即加载)
Spring容器可以通过其中一个接口来实现
显然用下面那种更好,启动的时候可能会慢一点,但是处理请求更快,ApplicationContext提供了更多的功能,我们直接使用这个即可。

Bean管理

分为两部分:

创建对象
注入属性

xml方式:

创建对象

id 和class,在bean标签内部注入属性
id 起个名字,通过这个名字拿到对象
class 类的全路径
name 和id作用一样,但是可以加特殊字符
创建对象时默认使用无参构造方法,没有无参构造方法会报错

依赖注入

1.使用set
property中设置属性,name是参数名 value是参数值
2.有参构造方法
需要创建有参构造方法
constructor-arg中设置属性name是参数名,value是属性值
3.p命名空间
需要申明xmln:

image-20220414175446804pname
pauthor

注入字面量:

设置的固定值都可以成为字面量
设置空值:

不写value,在

<property name="user">

<null/>

</property>
设置特殊符号:

例如<和> 会被误认为是xml的标签,可以加上&lt;&gt进行转义

可以加上CDATA进行标识

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yPuEIreN-1653534630038)(D:/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/picture/igHW3NFovbDzB1f.png)]

value可以写在标签头里面,也可以在property标签内部用<value></value>表示

注入外部bean的引用

需要编写外部bean的set方法

在xml配置文件中设置:

在这里插入图片描述

与字面量不同的是设置值用的标签是ref而不是value

注入的对象需要在配置文件中创建出来,ref的值就是被引用的id

内部bean和级联赋值

在设置bean的值的时候将这个bean创建出来:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7O9xuJPA-1653534630041)(D:/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/picture/UReAjgVKacPr6x3.png)]

得到属性要设置get方法,设置属性要设置set方法

还可以在引用赋值后,重新设置对象的属性值,会覆盖之前的属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SxW1SPGb-1653534630042)(D:/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/picture/nx2ByuUNscKwtEp.png)]

注入集合类型属性

xml设置集合类型的值

数组

array标签,里面用value标签设置值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QLJu0x2r-1653534780144)(D:/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/picture/nx2ByuUNscKwtEp.png)]

List

list标签,里面用value设置值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J6jiGIfY-1653534803303)(D:/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/picture/aVSZYf8c3kJAemW.png)]

map

map标签
里面用entry标签设置值,标签头设置key和value

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WQ8DtnlZ-1653534630046)(D:/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/picture/K7NmpaHMAjBv13l.png)]

set

用set标签里面用value设置值

image-20220415002724669

如果集合类型是对象,则把value标签改成<ref bean="xxx"></bean>的格式
在这里插入图片描述

如果要直接注入集合,则需要引入命名空间util

image-20220415003510637然后使用util:list标签,设置值的方式和上述一样,使用的时候用property name ref注入
在这里插入图片描述
在这里插入图片描述

两种bean 普通bean和工厂bean

普通bean,得到的类型和定义的类型相同,配置文件中定义的bean的类型就是我们要的类型
工厂bean,得到的类型和定义的类型可以不同
创建工厂bean需要实现FactoryBean接口,实现里面的getObject的方法,在这个方法里面设置最后得到的bean,最后得到的bean的类型用泛型来设置即实现FactoryBean接口时,得到的bean的类型就是T,拿到这个bean时,设置的类型也要和T一致,在配置文件中设置的bean是这个实现了FactoryBean的class,我们获取它时,会调用getObject方法拿到bean
bean的作用域,单例还是多例,默认是单例bean也就是多次调用getBean方法,拿到的对象是同一个,地址相同
可以用scope来设置,
singleton为单例,加载配置文件时会创建这个bean,
prototype代表多例,懒加载
request把bean放到request域
session把bean放到session域

bean的生命周期

1.调用无参构造方法创建实例
调用构造方法
2.为属性设置和引用赋值
调用set方法
3.调用初始化方法(需要配置)
调用xml中配置init-Method的方法
init-Method"initMethod"
4.使用bean
得到实例
5.调用销毁方法(需要配置)
调用xml文件中配置的destroy-method方法。
destroy-method=“destroyMethod"
用context.close方法关闭Spring容器时,会销毁bean,然后就会销毁所有的bean

手动装配

我们在xml文件中手动指定bean中的每个字段的值或其他bean的引用

自动装配

根据属性名称或者类型,自动将属性值装配(设置)进去
在bean标签中,加上autowire的字段,里面可以设置两种类型:byname bytype
byname:
autowire=“byname”
属性字段的变量名和xml中配置的bean的id一致,就可以自动装配进去
bytype:属性字段的类型和xml中有相同类型的bean就可以自动装配,如果有多个相同类型的bean则会报错。

以上都是基于xml设置Spring容器,而实际中我们会根据注解来进行自动装配,以上内容我们知道即可,在某些场景下可能会用到。

基于注解管理bean

注解是代码的特殊标记
格式:@注解名称(属性名称=属性值,属性名称=属性值)
注解可以加在类,方法,属性上面
Spring注解作用:简化xml配置,使bean管理更加方便

Spring关于bean管理的注解

@Component
普通组件
@Service
用在业务逻辑层
@Controller
用在web层
@Repository
用在持久层
上面四个注解的功能一样,都可以用来创建bean

以上注解都可以设置name,不设置name就默认是当前类名的首字母小写

使用步骤

使用这些注解需要引入aop
开启组件扫描:在xml中进行配置
加上context依赖(加入方式就是讲前面的p命名空间的p改成context)


配置扫描路径:<context:component-scan base-package=“com.demo”>

在这里插入图片描述
扫描多个包:用逗号隔开包名,或者写他们所在的公共目录
然后在需要加入Spring容器的类上加上注解
value属性指定bean的id值,如果省略id就是类名的首字母小写
加载配置文件->扫描包,如果有注解则创建bean->获取bean->使用bean

扫描包的时候可以设置过滤器:

在这里插入图片描述

use-default-filters=“false” :不使用默认的过滤器

标签内部:对这个包下面的带有Controller的注解的类进行扫描

设置哪些内容不去扫描:

image-20220419093637354

基于注解进行属性注入

@Autowired

根据属性类型进行注入

有多个相同类型(bean的type)的bean会报错

@Qualifier

根据名称(bean的id)进行注入

要和Autowired一起使用

@Qualifier(value = “userdao” )

在有多个类型相同的bean时,寻找名称相同的bean

@Resource

可以根据属性名称和类型进行注入

不加name:用type注入

加上name:用name注入

如果type不唯一,并且没有设置name,就将变量名当成name来注入

如果type不唯一,根据name找不到就会报错

在这里插入图片描述

@Value

注入普通类型(基本数据类型和String)

@Value(“abc”)

String name;

使用上述注解时,不需要我们设置set方法,他会自动帮我们配置

完全注解开发

创建配置类

@Configuration注解:作为配置类,代替xml配置文件

@ComponentScan(basePackages={“com.demo”})

开启组件扫描

编写启动类

替换容器类型:AnnotationConfigApplicationContext(SpringConfig.class)

实际中基于Springboot启动

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值