spring学习(一)spring-ioc、di和循环依赖

0. 前言

Spring比较重要的特性就包含IOC和DI,其中的也会产生循环依赖,线程安全等问题。
bean中的各个参数

id : 唯一标识
		name : bean的名字,一个bean标签可以有多个别名,多个别名间使用空格/逗号/分号分割。
		alias :bean的新的名字,一个bean标签可以有多个别名,多个别名间使用空格/逗号/分号分割。
		class : 当前bean对象的具体类名
		abstract : 对象不可直接使用。 必须被其他的bean对象继承。
			设定对象的模板,可以减少一定的配置。
		parent : 继承已定义的对象。 继承的父对象类型必须兼容子对象类型。
			父对象的类型必须是子对象类型的同类型或父类型。
		factory-bean : 引用已定义的动态工厂对象
		factory-method : 调用工厂类中的工厂方法
		scope : 对象的作用域。 对象如何创建,创建多少个对象。
			可选值 :
			singleton : 默认值,单例的,在读取配置文件的同时创建唯一的一个对象
			prototype : 多例的。每次通过getBean方法获取对象时,创建对象。
			request : 请求变量作用域, 一个请求创建一个对象
			session : 一个HttpSession会话创建一个对象
			global-session : 在portlet技术中的servletContext,一个应用一个对象
			application : 基础web项目中的应用, 一个应用一个对象。

1. IOC

IOC是指Inversion of Control, 即控制反转。
单纯的作用就是是将对象的生命周期控制权限交由Spring容器管理。并且通过Spring容器实现了各层代码之间的解耦, 让代码没有依赖关系. 且实现了代码的可插拔性。

1.1. 构造方法创建

构造方法分为无参构造有参构造
在配置文件xml(applicationContext.xml)中 ,配置bean
构造方法创建

<!-- 无参构造 -->
<bean id="" class="" />
 <!-- 有参构造 -->(配置的参数必须和构造方法一致)
 <bean id="" class="" >
	 <constructor-arg index="" name="" type="" value="" />
</bean>

1.2. 工厂方法管理

工厂方法分为静态工厂构造动态工厂构造

 <!-- 静态工厂 -->
<bean id="" 
	class="静态工厂类的全命名" 
	factory-method="静态工厂方法名" />
  <!-- 动态工厂 -->(配置的参数必须和构造方法一致)
<bean id="factory" class="" />
<bean id="product" factory-bean="factory"
	factory-method="factoryMethodName" >
	<constructor-arg index="" name="" type="" value="" />
</bean>

2. DI依赖注入

为Spring容器管理的对象中的属性,注入数据。

2.1. 构造方法注入

与上边IOC有参构造方法创建一致(bean对应实体类必须有参构造方法才能使用构造方法注入,并且入参要和参数一致)

 <bean id="" class="" >
	 <constructor-arg index="" name="" type="" value="" />
</bean>

2.2. setter方法注入

  <bean id="" class="" >
	 <property name="" value="" />
	<property name="" ref="" />
</bean>

3. 自动装配

自动装配的配置的位置,以及各种形式的匹配规则

3.1. beans配置自动装配

<beans default-autowire="default|no|byName|byType|constructor">

3.2. bean配置自动装配

<bean autowire="default|no|byName|byType|constructor">

3.3. 各种方式的含义

	default : 默认值, 与no含义一致。代表没有自动装配
	no : 无自动装配
	byName : 使用property的名称和bean的名称进行匹配,如果匹配一致则装配。
		只能自动装配复杂类型。如String等简单类型无法自动装配
	byType : 使用property的类型和bean的类型进行匹配。如果匹配一致则装配。
		有错误可能。 如果有多个bean对象类型一致或匹配,则可能抛出异常
		只能自动装配复杂类型。如String等简单类型无法自动装配
	constructor : 使用有参数的构造方法进行数据的注入。
		先使用byName进行装配,如果没有命名一致的bean,使用byType进行自动装配

4. 循环依赖的问题

循环依赖:bean之间存在直接或间接的依赖关系,例如A和B互相依赖,或者A依赖B,B依赖C,C依赖A,或者A依赖A。
三级缓存(存放不同类型的Bean)

  1. singletonObjects:第一级缓存,里面放置的是初始化后的单例对象;
  2. earlySingletonObjects:第二级缓存,里面存放的是提前曝光的单例对象;原始对象,未赋值。
  3. singletonFactories:第三级缓存,里面存放的是要被实例化的对象的对象工厂。用来生成原始Bean并放入二级缓存。

假设A和B互相依赖

在这里插入图片描述
核心:当一个Bean调用构造函数进行实例化后,即使属性还未填充,就可以通过三级缓存向外暴露依赖的引用值(所以循环依赖问题的解决也是基于Java的引用传递)。即Bean的实例化以及依赖注入两个过程分离。

  • bean之间通过构造方法构造依赖?
    通过@Lazy注解。
  • 多实例(prototype)的Setter注入?
    不能解决,需要单例。
  • 单例的代理对象Setter注入?
    使用@Lazy注解或者使用@DependsOn注解指定加载先后关系。

5. 线程安全问题

  • Bean默认是singleton,所以Spring框架里除了pojo基本都是单例对象,不更改对应Bean的成员变量就不会出现线程安全问题,例如Controller层,Servise层,dao层等,自始至终只有一个;好处就是为了防止每次请求都会重新建立对象,造成性能问题;
  • 实体pojo都是新的,每次返回都不会互相干扰;
  • 有些对象会依靠ThreadLocal和线程绑定,不会出现线程安全问题(数据库连接等)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值