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
构造方法创建



 (配置的参数必须和构造方法一致)
 
	 

1.2. 工厂方法管理

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

 

  (配置的参数必须和构造方法一致)


	

2. DI依赖注入

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

2.1. 构造方法注入

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

 
	 

2.2. setter方法注入

  
	 
	

3. 自动装配

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

3.1. beans配置自动装配


3.2. bean配置自动装配


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互相依赖

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

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

5. 线程安全问题

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

你可能感兴趣的:(框架学习,spring,学习,java)