通俗易懂话spring的底层原理

spring是目前java开发必须熟练掌握的框架,面试的时候spring也是必问的问题之一。下面将以Q&A的方式回答面试中可能出现的spring框架问题。其中重点将会以不同的颜色标识出来。

1.Q:什么是spring?

   A:Spring是一个轻量级的,用来装javabean的,控制反转(IoC)面向切面(AoP)的容器框架,它可以使得开发者更专注于应用程序的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。它就像万能胶,可以起到连接的作用,例如最常用到的ssm和ssh。

还可以继续补充:

在说spring的特点之前得说下IoC和AoP

IoC(或依赖注入DI=Dependency Injection:

就是由spring来负责控制对象的生命周期和对象间的关系。所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转(IOC)。 IoC还有一个另外的名字:“依赖注入 (DI=Dependency Injection)”  ,即由容器动态的将某种依赖关系注入到组件之中 ,案例:实现Spring的IoC


AoP:

就像我们在切菜一样,比如说我们要切好几根同样的火腿肠,为了方便通常都是几根一起切,在合适长度的位置统一进行横向切割。也就是把可重用的功能提取出来,然后将这些通用功能在合适的时候织入到应用程序中;比如安全,日记记录,这些都是通用的功能,我们可以把它们提取出来,然后在程序执行的合适地方织入这些代码并执行它们,从而完成需要的功能并复用了这些功能。


2.Q:spring的特点有:

A:(1)方便解耦,简化开发

通过上面我们了解到了IoC的好处,就是能够将对象之间的依赖关系进行解耦合,让用户能够更加专注于上层应用。

(2)AOP编程的支持

通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP(oop(Object Oriented Programming,面向对象编程))实现的功能可以通过AOP轻松应付。

(3)声明事物的支持

在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

(4)方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便的测试Spring程序。

(5)方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持。

(6)降低Java EE API的使用难度

Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

(7)Java 源码是经典学习范例

Spring的源码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。


3.Q:bean的作用域:

A:Spring Bean 中所说的作用域,在配置文件中即是“scope

在面向对象程序设计中作用域一般指对象或变量之间的可见范围。

而在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围

(1)singleton:

就像多个人公用一个工具一样。当Bean的作用域为singleton的时候,Spring容器中只会存在一个共享的Bean实例,所有对Bean的请求只要id与bean的定义相匹配,则只会返回bean的同一实例。单一实例会被存储在单例缓存中,为Spring的缺省作用域。

可以对那些非线程安全的对象采用单实例模式。

(2)prototype:

就像买电脑一样,买了后spring则不管实例的销毁了。每次对该Bean请求的时候,Spring IoC都会创建一个新的作用域对于有状态的Bean应该使用prototype,对于无状态的Bean则使用singleton。

在默认情况下,Spring容器在启动时不实例化prototype这种bean。此外,Spring容器将prototype的实例交给调用者之后便不在管理他的生命周期了。

(3)request:

Request作用域针对的是每次的Http请求,Spring容器会根据相关的Bean的定义来创建一个全新的Bean实例。而且该Bean只在当前request内是有效的。

(注:request和prototype的区别:request依赖于web应用,request就类似与你的servlet,多个用户访问一个servlet,当然是访问servlet的多个实例,prototype实际上是new出来的,你想想,你的bean里new了一个对象,为什么要让spring给你销毁。prototype没有什么好不好的,只不过它能做singleton所不能做得(创建多个实例),在web项目之外也可以做request所不能做得事。prototype的销毁你不必关心,调用它的bean销毁了,它也就销毁了。request是web里所特有的。)

(4) session:

针对http session起作用,Spring容器会根据该Bean的定义来创建一个全新的Bean的实例。而且该Bean只在当前http session内是有效的。

(5)global session:

类似标准的http session作用域,不过仅仅在基于portlet的web应用当中才有意义。Portlet规范定义了全局的Session的概念。他被所有构成某个portlet外部应用中的各种不同的portlet所共享。在global session作用域中所定义的bean被限定于全局的portlet session的生命周期范围之内。

与session大体相同,但仅在portlet应用中使用。

详见Spring学习----------Spring Bean 的5种作用域介绍


4.Q:bean的生命周期?

A:有很多文章都有写bean的生命周期,例如bean的生命周期,Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:

(1)Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法

(2)Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法

(3)容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

(4)工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

如下述说:

在一个 bean 实例被初始化时,需要执行一系列的初始化操作以达到可用的状态,包括实例化容器级生命周期接口,然后调用bean的构造器,再Bean级生命周期接口方法注入属性初始化bean,就可以执行正常调用了。同样的,当一个 bean 不在被调用时需要执行销毁bean的方法,从 bean容器中移除。

Spring 框架提供了以下四种方式来管理 bean 的生命周期事件:
1、InitializingBean 和 DisposableBean 回调接口
2、针对特殊行为的其他 Aware 接口
3、Bean 配置文件中的 Custom init()方法和 destroy()方法
4、@PostConstruct 和@PreDestroy 注解方式


5.Q:spring属性注入方式

A:常用的注入方式主要有三种:构造方法注入,setter注入,基于注解的注入。

详细可见spring注入方式及常见问题,值得一看


6.Q:spring的aop中存在的两种动态代理?

A: 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用 。Spring AOP中使用了两种动态代理,一种是JDK的动态代理,一种CGLIB的动态代理。JDK的动态代理必须指定接口,这些接口都是已经被代理对象实现了的;而CGLIB代理则不需要指定接口。

两种代理的优缺点:

(1)若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。 
优点:因为有接口,所以使系统更加松耦合 
缺点:为每一个目标类创建接口
(2)若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。 
优点:因为代理类与目标类是继承关系,所以不需要有接口的存在。 
缺点:因为没有使用接口,所以系统的耦合性没有使用JDK的动态代理好。
详见:Spring的两种代理方式:JDK动态代理和CGLIB动态代理


参考:

1.https://blog.csdn.net/sujin_/article/details/78700158                   什么是spring,它能够做什么?  

2.https://blog.csdn.net/javaxuexi123/article/details/80804800        Spring面试底层原理的那些问题,你是不是真的懂Spring?

3.https://www.cnblogs.com/song1314/articles/4568379.html         spring特点与好处

4.https://blog.csdn.net/qq_38676810/article/details/80490682      Spring是什么?

5.https://blog.csdn.net/jishuizhipan/article/details/79391651         Spring学习----------Spring Bean 的5种作用域介绍

6.https://www.cnblogs.com/zrtqsk/p/3735273.html                        Spring Bean的生命周期(非常详细)

7.https://blog.csdn.net/a909301740/article/details/78379720        Spring常用的三种注入方式

8.https://www.cnblogs.com/shuai-server/p/9011334.html               spring的底层原理

9.https://blog.csdn.net/cckevincyh/article/details/54962920           Spring的两种代理方式:JDK动态代理和CGLIB动态代理

10. https://blog.csdn.net/qq_35661171/article/details/80898110    29题弄懂Spring底层原理,这些题目你都会吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值