Spring进阶

Spring进阶

BeanFactory 和 ApplicationContext

​ 都是spring框架定义的接口

​ BeanFactory是spring框架中最基础的接口,定义了管理类最基本的方法(例如:获取实例,基本的判断等)

​ spring要生成并管理对象,底层使用的是工厂模式

​ AppLicationContext也间接性的继承了Beanfactory接口,并扩展了功能,他们俩的关系可以说是心脏与躯干的关 系;BeanFactory是心脏,ApplicationContext是躯干.

区别:

  • BeanFactory是最原始的Factory,它不支持AOP,Web等spring插件,而ApplicationContext不仅包含了BeanFactory的所有功能,还支持spring的各种插件.

  • BeanFactory是spring的最基础设施,面向spring,而ApplicationContext则是面向开发者,相比BeanFactory而言,几乎所有场合都可以直接使用ApplicationContext

  • 使用BeanFactory实现在spring启动时,不会创建单例bean,而ApplicationContext则是创建单例bean

SpringBean的生命周期

spring创建出来的对象与我们自己new的对象是不同的

宏观上来讲,springBean的生命周期可以分为5个阶段:

  1. 实例化
  2. 属性赋值
  3. 初始化
  4. 将bean对象放在容器中使用
  5. 销毁

细化:

1.对象实例化

2.属性赋值

3.1如果Bean实现BeanNameAware执行setBeanName

3.2如果Bean实现BeanFactoryAware或者ApplicationContextAware设置工厂 setBeanAware或者上下文对象setApplicationContext对象

3.3如果存在类实现 BeanPostProcessor(AOP),执行postProcessBeforeInitialization

3.4如果Bean实现 InitializingBean执行afterPropertiesSet

3.5 如果存在类实现 BeanPostProcessor(AOP) ,执行postProcessAfterInitialization

4.完整的Bean创建好,将Bean对象放入容器中,可以使用

5.销毁; 如果Bean实现DisposableBean执行destory

spring的单例bean是安全的吗?

spring本身对线程安全问题不做处理

根据scope的值来决定线程是否安全

单例 不安全

原型 安全 创建多个对象,每个对象都包含一份成员变量(由于每次创建一个对象,也就是说线程之间不存在bean共享,所以不存在线程安全问题)

如果单例模式中的变量是无状态的(例如:Controller,Service,Dao 都是依赖注入的变量,他们只关注方法本身),那么就是线程安全的

如果单例模式中的变量是无状态的(例如: 成员变量等 当请求过来,都共享一个变量,就存在资源竞争的问题)他们就是线程不安全的

单例模式中解决线程不安全的办法:

1.可以将他设置成原型模式

2.可以将变量存储在 ThreadLocal中 用的时候取出来,这样每个请求过来都分配一个单例,就不存在资源竞争的问题.

Bean循环依赖

java的循环依赖场景有:

(1)构造器的循环依赖,构造器的循环依赖无法解决,只能抛出异常

(2)field属性的循环依赖

​ 就是A对象依赖了B对象,B对象依赖了A对象

如果不考虑spring的问题,那么就没有问题,因为对象之间的相互依赖和正常

但是在spring的环境下,就是一个问题;

这是因为在spring中,一个对象是经过一系列bean的生命周期创建出来的,正是因为有了生命周期才会出现循环依赖的问题

产生的原因: A创建时===>需要B===>B创建时===>需要A 从而产生循环

spring框架内部有三级缓存:

singletonObjects(一级缓存):用于保存实例化,注入,初始化完成的bean的实例

earlySingletonObjects(二级缓存):用于保存实例化完成的bean实例

singletonFactories(三级缓存):用于保存bean创建工厂,以便于后面扩展有机会创建代理对象

怎样解决循环依赖的问题:

A,B循环依赖,先初始化A,先保存一个A的半成品,在去初始化依赖的B,初始化B时发现B依赖A,则注入半成品A,最后初始化完成B,在回去初始化A就完成. 这样只需要一个能缓存半成品的A的Map就可以了.也就是二级缓存,但是如果这个对象存在代理,那么就需要三级缓存缓存代理.

总结:二级缓存可以缓存依赖,三级缓存可以缓存代理.

建模语言(UML):

建模语言是用来设计软件蓝图的可视化建模语言;

它能为软件开发的所有阶段提供模型化和可视化支持. 而且融入了软件开发领域的新思想,新方法,新技术; 使设计人员进一步缩小了设计时间,减少了开发成本

1.类

是具有相同属性,方法和关系的对象的抽象,它封装了数据和行为,是面向对象设计的基础,具有封装,继承,多态三大特性.在UML中,类使用包含类名,属性和操作且带有分隔线的矩形来表示.

2.接口

接口是一种特殊的类,它具有类的结构但不可被实例化,只能被子类实现.它包含抽象操作,但不包含属性.它描述了类或组件对外可见的动作.在UML中,接口使用一个带有名字的小圆圈来表示.

3.类图

类图是用来显示系统中的类,接口,协作以及他们之间的静态结构的一种静态模型.它主要用于描述软件系统的结构化设计,帮助人们简化对软件系统的理解.它是系统分析与设计阶段的产物,也是系统编码和测试的重要模型依据.

类之间的关系:
1.依赖关系

是一种使用关系,它是单向之间耦合度最弱的一种关联方式,是临时性关联.

在代码种,某个类的方法通过局部变量,方法的参数或者对静态方法的调用来访问另一个类(以来的类)中的某些方法

在UML图中, 用一个带虚线的箭头来表示,箭头从使用类指向被依赖的类

2.关联关系

是一种对象之间的一种引用关系,用来表示一类对象与另一类对象之间最常用的一种联系.例如:老师和学生,妻子和丈夫.

关联可以是双向的,也可以是单向的.在UML图中双向可以用带俩个箭头或者没有箭头的实线来表示,单向则用一个箭头的实线来表示.

在代码中通常将一个对象当成另一个对象的成员变量来实现关联关系.

3.聚合关系

聚合关系是一种强关联关系,是整体和部分之间的关系,是has-a的关系.

聚合关系是通过成员对象来实现的,其中成员对象是整体的一部分,但是成员对象可以脱离对象而独立出来.例如:学校和老师之间的关系,即使学校停办了,老师依然存在.

在UML图中,聚合关系可以用带菱形的实线来表示,菱形指向整体.

4.组合关系

组合关系表示类之间整体与部分之间的关系,但他是一种更加强烈的聚合关系.

在组合关系中,整体对象可以控制部分对象的生命周期,一旦整体不存在,部分也将消失,部分对象不能脱离整体对象.例如: 身体和头之间,没有了身体,头也就不存在了

在UML图中,组合关系用带实心菱形的实线来表示,菱形指向整体.

5.泛化关系

是一种耦合度最高的一种关系,是子类和父类之间的关系,是is-a的关系.

在UML图中,用空心三角箭头的实线来表示,箭头从子类指向父类.

在代码中,使用面向对象的继承机制,来实现泛化关系 例如:Student类和Teachers类都是Person类的子类

6.实现关系

是接口与类之间的关系.在这种关系中,类实现了接口,类中的操作实现了接口中所声明的所有的抽象操作.

在UML图中,实现关系使用带空心的三角箭头的虚线来表示,箭头从实现类指向接口

面向对象设计原则

在设计面向对象的过程中,首先要考虑如何提升软件系统的可维护性和可复用性.

单一职责:

是最简单的面向对象设计原则,用于控制类的粒度大小;

可以说是一个类只负责一个功能领域中的职责.

优点:低耦合,高内聚

开闭原责:

是面向对象可复用设计的第一块基石,是最重要的面向对象设计原则.

开闭原责即对扩展开放,修改封闭; 抽象化是开闭原则的关键

优点:

适应性和灵活性强;稳定性和延续性好;可复用性和可维护性好

里氏替换原则:

是实现开闭原则的重要方式之一;

在任何父类出现的地方都可以用它的子类来替换(多态);

且不影响功能

需要注意:

  1. 子类必须实现在父类中声明的所有方法
  2. 在运用时,尽量将父类设计成抽象或这接口的形式,让子类继承或者实现父类接口,并实现在父类中声明的方法,运行时,子类实例代替父类实例,可以更好的扩展功能.

依赖倒置:

高层模块不应该依赖底层模块,俩者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象;

也就是抽象层编程,面向接口编程

接口隔离:

使用多个专门的接口,而不实现总接口,不强迫新功能实现不需要的方法

迪米特原则:

一个对象应当对其他对象尽可能少的了解,降低耦合.例如: 买房时,买家与卖家之间通过中介买房,二者之间互不了解.

组合/聚合复用原则:

优先使用组合,使系统更加灵活,其次使用继承,达到复用的目的.

一般而言:如果俩个类的关系是"Has-A"则用组合或聚合,如果是"Is-A"则用继承

总结:

七大原则不是强制性的,更多的是建议.遵循这些可以更好的规范我们的系统设计和代码习惯,但不是所有的场景都需要,不要为了遵循一个原则而使得整个系统变得更加庞大,甚至影响项目进度.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值