什么是spring?
Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用。Spring框架目标是简化Java企业级应用开发,并通过POJO为基础的编程模型促进良好的编程习惯
使用Spring框架的好处是什么?
轻量:Spring 是轻量的,基本的版本大约2MB。
控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
容器:Spring 包含并管理应用中对象的生命周期和配置。
MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。
Spring由哪些模块组成?
简单可以分成6大模块:
Core AOP ORM DAO Web Spring EE
什么是Spring的依赖注入?
依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。
有哪些不同类型的IOC(依赖注入)方式?
构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。
工厂注入:这个是遗留下来的,很少用的了!
哪种依赖注入方式你建议使用,构造器注入,还是 Setter方法注入?
讲道理,你两种依赖方式都可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖。
什么是Spring beans?
Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中
这里有四种重要的方法给Spring容器提供配置元数据。
XML配置文件。
基于注解的配置。
基于java的配置。
Groovy DSL配置
解释Spring框架中bean的生命周期
Spring容器 从XML 文件中读取bean的定义,并实例化bean。
Spring根据bean的定义填充所有的属性。
如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法。
如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。
如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。
如果bean实现IntializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用此初始化方法。
如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。
如果bean实现了 DisposableBean,它将调用destroy()方法。
解释不同方式的自动装配
no:默认的方式是不进行自动装配,通过显式设置ref 属性来进行装配。
byName:通过参数名 自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和该bean的属性具有相同名字的bean。
byType::通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。
constructor:这个方式类似于byType, 但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
autodetect:首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式。
只用注解的方式时,注解默认是使用byType的!
IOC的优点是什么?
IOC 或 依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。
IOC容器支持加载服务时的饿汉式初始化和懒加载。
简要谈谈AOP
说到AOP 首先想到的是什么 正交性 因为正交性的另一个有趣的变体就是面向切面编程
举个例子,如果多个事务中一个发生变化不会影响其他事务,这些事务就是正交的 在设计良好的系统中,数据库代码与用户界面是正交的;
你可以改动界面,而不影响数据库,更改数据库,而不用改动界面 AOP让你在一个地方表达本来会分散在你源码各处的某种行为
例如日志消息是在源码各处,通常显式地调用某个日志函数生成的,通过AOP,你把日志功能正交地实现到要进行的日志记录的代码中
使用AOP的JAVA版本,你可以通过编写aspect,在进入类Fred的任何方法时写日志消息 如果你把这个写进你的代码,就会生成追踪消息,否则,你就不会看到任何消息,不管怎样,你原来的源码都没有变化
AOP实现原理
Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和CGLIB 动态代理。JDK 动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK 动态代理的核心是InvocationHandler接口和Proxy类。
如果目标类没有实现接口,那么 Spring AOP 会选择使用 CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final,那么它是无法使用 CGLIB 做动态代理的。
怎么回答面试官:你对Spring的理解
Spring最初诞生时候就是,控制反转和非侵入式。再讲讲Springboot 主要是在没有Springboot的时候 大家是怎么写代码的呢,Spring是为了解决什么问题?
Sring框架用到了那些设计原则
代理模式:在 AOP 和 Remoting 中被用的比较多。
单例模式:在 Spring 配置文件中定义的 Bean 默认为单例模式。
Spring 的单例实现原理
比如Spring 对 Bean 实例的创建是采用单例注册表的方式进行实现的,而这个注册表的缓存是 ConcurrentHashMap 对象。
模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
前端控制器:Spring 提供了 DispatcherServlet 来对请求进行分发。
视图帮助(View Helper ):Spring 提供了一系列的 JSP 标签,高效宏来辅助将分散的代码整合在视图里。
依赖注入:贯穿于 BeanFactory / ApplicationContext 接口的核心理念。
工厂模式:BeanFactory 用来创建对象的实例。