Spring
前言
Github:https://github.com/HealerJean
1、名词解释
1.1、IoC和DI
IoC
叫控制反转,是Inversion of Control
的缩写,控制反转是把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。
所谓的”控制反转”就是对组件对象控制权的转移,从程序代码本身转移到了外部容器,由容器来创建对象并管理对象之间的依赖关系。
当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象,是容器在对象初始化时不等对象请求就主动将依赖传递给它。通过IOC反转控制DI依赖注入完成各个层之间的注入,使得层与层之间实现完全脱耦,增加运行效率利于维护。
1.1.1、 ioc有3种注入方式
1、setter方法注入
2、构造器注入
3、根据注解注入
2.1、AOP
spring的AOP:面向切面编程,实现在不改变代码的情况下完成对方法的增强。好处就是你只需要干你的正事,其它事情别人帮你干。
2.1.1、简单理解
面向切面编程的目标就是分离关注点。什么是关注点呢,就是你要做的事,就是关注点。
举个例子,假如你是个公子哥,没啥人生目标,天天就是衣来伸手,饭来张口,整天只知道玩一件事!那么,每天你一睁眼,就光想着吃完饭就去玩(你必须要做的事),但是在玩之前,你还需要穿衣服、穿鞋子、叠好被子、做饭等等等等事情,这些事情就是你的关注点,但是你只想吃饭然后玩,那么怎么办呢?这些事情通通交给别人去干。在你走到饭桌之前,有一个专门的仆人A帮你穿衣服,仆人B帮你穿鞋子,仆人C帮你叠好被子,仆人C帮你做饭,然后你就开始吃饭、去玩(这就是你一天的正事),你干完你的正事之后,回来,然后一系列仆人又开始帮你干这个干那个,然后一天就结束了!
从Spring的角度看,AOP最大的用途就在于提供了事务管理的能力。事务管理就是一个关注点,你的正事就是去访问数据库,而你不想管事务(太烦),Spring在你访问数据库之前,自动帮你开启事务,当你访问数据库结束之后,自动帮你提交/回滚事务!,AOP避免了我们每次都要手动开启事物,提交事务的重复性代码,使得开发逻辑更加清晰。
2.1.2、产生由来
AOP(Aspect-OrientedProgramming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。
OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。
例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。
这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。 AOP技术利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。 所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,并有利于未来的可操作性和可维护性。
使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。 业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。
横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。
2、Spring 框架中都用到了哪些设计模式
1、工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
2、单例模式:Bean默认为单例模式。
3、代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
4、模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
6、观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。
3、Spring Bean的生命周期
1、Bean
容器找到配置文件中 Spring
Bean
的定义。
2、Bean
容器通过构造器或其他方式创建一个Bean的实例。
3、如果涉及到一些属性值 利用 set()
方法设置一些属性值。
4、如果 Bean
实现了 BeanNameAware
接口,调用 setBeanName()
方法,传入Bean的名字。
5、如果 Bean
实现了 BeanClassLoaderAware
接口,调用 setBeanClassLoader()
方法,传入 ClassLoader
对象的实例。
6、如果 Bean
实现了 BeanFactoryAware
接口,调用 setBeanFactory()
方法,传入 BeanFactoryr
对象的实例。
7、如果 Bean
实现了 ApplicationContextAware
接口,调用 setApplicationContext()
方法,传入 ApplicationContext
对象的实例。
8、与上面的类似,如果实现了其他 *.Aware接口,就调用相应的方法。
9、如果有和加载这个 Bean
的 Spring
容器相关的 BeanPostProcessor
对象,执行postProcessBeforeInitialization()
方法
10、如果Bean实现了@PostConstruct
11、如果Bean实现了InitializingBean
接口,执行afterPropertiesSet()
方法。
12、如果 Bean 在配置文件中的定义包含 init-method
属性,执行指定的方法。
13、如果有和加载这个 Bean
的 Spring
容器相关的 BeanPostProcessor
对象,执行postProcessAfterInitialization()
方法
14、当要销毁 Bean
的时候,如果 Bean 实现了 DisposableBean
接口,执行 destroy()
方法。
15、当要销毁 Bean
的时候,如果 Bean 在配置文件中的定义包含 destroy-method
属性,执行指定的方法。