Spring概述

什么是spring?

spring是一个轻量级的java开发框架,它的呈现简化了企业级利用开发的难度,是Java开发人员更专一于业务代码逻辑的编写。它有两个特点:IOC管制翻转和AOP面向切面编程。

谈谈IOC和AOP

IOC(管制翻转)

平时咱们须要应用对象,都是本人new一个进去。这样在咱们我的项目中,就会呈现大量的冗余对象。而IOC管制翻转所在的事件,就是咱们之前本人new对象的操作取代了,对象由spring的IOC容器创立并治理。咱们须要用到一个对象的时候,只须要向IOC容器的beanFactory索取即可。总体来说,就是将对象创立的权力从程序员手上,交到了IOC容器手中。

AOP(面向切面编程)

AOP是对OOP(面向对象编程)的一种补充,面向对象编程是将事务的特色和行为形象成一个个对象,而面向切面编程则是在一个个对象的根底上的进一步形象。找寻这些对象都须要做的事件,而后就成一把刀一样在这些对象上切出一个面,来退出对象都须要做的事件。AOP是通过动态代理或者动静代理来实现的,其余动静代理更为灵便,分为Java自带的代理接口和Cglib动静代理。咱们通常应用AOP来实现日志、事务、安全检查相干的操作。

Spring由哪些模块组成?

  1. spring core:提供了框架的根本组成部分,如IOC、DI等性能。
  2. spring beans:提供了BeanFactory,是工厂模式的一个经典实现,spring将治理对象称为bean。
  3. spring context:构建与core封装包根底上的context封装包,提供了一种框架式的对象拜访办法。
  4. Spring jdbc:拱了一个JDBC的形象层,打消了繁琐的JDBC编码和数据库厂商特有的错误代码解析,用于简化JDBC的操作。
  5. Spring AOP:提供了面对想切面的编程实现,让你能够自定义拦截器、切点等。
  6. Spring web:提供了针对web开发的继承个性,例如文件上传,利用servlet listeners进行IOC容器初始化和针对web的applicationContext。
  7. Spring test:次要为测试提供反对的,反对应用Junit或TestNG对Spring组件进行单元测试和集成测试。

Spring框架中都用到了哪些设计模式?

  1. 工厂模式:BeanFactory就是简略工厂模式的体现的,用来创建对象的实例。
  2. 单例模式:Bean默认为单例模式。
  3. 代理模式:Spring的AOP面向切面编程就用来到了JDK的动静代理和CGLIB动静代理。
  4. 模板办法:比方,RestTemplate、JpaTemplate都用了模板办法,用来解决代码反复的问题。
  5. 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态产生扭转时,所有依赖于它的对象都会失去告诉被制动更新,如Spring中listener的实现ApplicationListener

Spring如何治理事务的?

Spring的事务申明有两种形式:编程式和申明式。
spring次要是通过“申明式事务”的形式对事务进行治理,即在配置文件、注解进行事务申明,通过AOP将事务切面切入程序,最大的益处是大大减少了代码量。

Spring IOC容器配置Bean的形式?

  1. XML文件bean标签的形式
  2. 注解的形式
  3. java Config代码类的形式

Bean是如何被治理的?【重点】

在spring框架中,一旦把一个bean纳入到Spring IOC容器之中,这个bean的生命周期就会交由容器进行治理,个别担当管理者角色的是BeanFactory或ApplicationContext。认识一下Bean的生命周期流动,对更好的利用它有很大的帮忙。
详情来说次要有四个阶段:实例化、初始化、应用、销毁。

  1. 首先容器启动后,会对scope为singleton且非懒加载的bean进行实例化。
  2. 依照bean定义信息配置信息,注入所有的属性。
  3. 如果bean实现了BeanNameAware接口,会回调该接口的setBeanName()办法,传入该Bean的id,此时该bean就取得了本人在配置文件中的id。
  4. 如果Bean实现BeanFactoryAware接口,会回调该接口的setBeanFactory()办法,传入该bean的BeanFactory,这样该bean就取得了本人所在的BeanFactory。
  5. 如果Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()办法,传入该Bean的ApplicationContext,这样该bean就取得了本人所在的ApplicationContext。
  6. 如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()办法。
  7. 如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()办法。
  8. 如果Bean配置了init-method办法,则会执行init-method配置的办法。
  9. 如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()办法。
  10. 通过流程9之后,就能够正式应用该bean了,对于scope为singleton的bean,spring的ioc容器中会缓存一份该bean的实例,而对于scope为prototype的bean,每次被调用都会new一个新的对象,申明周期就交给调用方治理了,不再是Spring容器进行治理了。
  11. 容器敞开后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()办法。
  12. 如果Bean配置了destroy-method办法,则会执行destroy-method配置的办法,至此,整个Bean的生命周期完结了。

Spring中的主动拆卸有哪些限度?

  • 如果应用了结构器注入或者settter注入,那么将笼罩主动拆卸的依赖关系。
  • 根本数据类型的值、字符串字面量、类字面量无奈应用主动拆卸来注入。
  • 优先应用显式的拆卸来进行更准确的依赖注入而不是应用主动拆卸。

Spring中Bean的作用域有哪些?

  1. singleton作用域: 在spring IOC容器中仅仅存在一个Bean实例,Bean是以单例形式存在的,为默认值。
  2. prototype作用域:每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXXXBean().
  3. request作用域:每一个http申请中的bean是单例的,该作用域仅实用于WebApplicationContext环境
  4. session作用域:每一个session中的bean是单例的,不同Session应用不同的Bean,仅实用于WebApplicationContext环境
  5. globalSession作用域:个别用于Portlet应用环境,该作用域仅实用于WebApplicationContext环境。

什么是IOC和DI?DI是如何实现的?

IOC是管制反转的意思,之前没有引入IOC容器时,退出对象A依赖于对象B,那么对象A在创立初始化或者运行到某一点的时候,须要用到B对象时,就须要咱们手动本人去创立一个B对象。这个时候无论是创立B对象,还是应用B对象的控制权都在咱们本人的手上。然而在引入IOC容器之后,情景就实现变动了,当对象A运行过程中须要用到对象B的时候,不是须要咱们本人再手动创立一个B对象了,而是IOC容器会主动创立一个B对象,帮忙咱们注入到A对象中。通过前后的比照,咱们不难发现。对象A获取依赖对象B的过程,由被动行为编程了被动行为。对象的创立、管理权,从咱们手上转移到了IOC容器中了。这就是IOC管制翻转。
对于DI依赖注入:其实DI与IOC管制反转是从不同方面形容的同一件事件,都是指将对象的创立、管理权从使用者的手上,通过依赖注入到IOC容器中。

IOC的优缺点

长处

升高了类之间的耦合,可维护性失去了进步。

毛病

  • 因为IOC容器中对象的生成是通过反射造成的,所以在运行效率上会有一些损失。
  • 要做一些额定的配置工作

你如何了解AOP中失去连接点(Joinpoint)、切点(Pointcut)、加强(Advice)、引介(Introduction)、织入(Weaving)、切面(Aspect)这些概念?

  • 连接点:程序执行的某个特定地位(如:某个办法调用前、调用后,办法抛出异样后)。一个类或一段程序代码领有一些具备边界性质的特定点,这些代码中的特定点就是连接点。Spring仅反对办法的连接点。
  • 切点(Pointcut):如果连接点相当于数据中的记录,那么切点相当于查问条件,一个切点能够匹配多个连接点。Spring AOP的规定解析引擎负责解析切点所设定的查问条件,找到对应的连接点。
  • 加强(Advice):加强是植入到指标类连接点上的一段程序代码。Spring提供的加强连贯口都是带方位名的。如:BeforeAdvice、AfterReturningAdvice、ThrowsAdvice等。
  • 引介(Introduction):引介是一种非凡的加强,它为类增加一些属性和办法。这样,即便一个业务类本来没有实现某个接口,通过引介性能能够动静的为该业务类增加接口的实现逻辑。让业务类成为这个接口的实现类。
  • 织入(Weaving):织入是将加强增加到指标类具体连接点上的过程,AOP有三种织入形式:

    1. 编译期织入:须要非凡的Java编译期(例如AspectJ的ajc)
    2. 装载期织入:要求应用非凡的类加载器,在装载类的时候对类进行加强
    3. 运行时织入:在容许时为指标生成代理实现加强。spring采纳动静代词的形式实现了运行时织入,而AspectJ采纳了编译期织入和装载期织入的形式。
  • 切面(Aspet):切面是由切点和加强(引介)组成的,它包含了对横切关注性能的定义,也包含了对连接点的定义。

Spring主动拆卸的形式有哪些?

  1. no:不进行主动拆卸,而是手动设置Bean的依赖关系
  2. byName:依据Bean的名字进行主动拆卸
  3. byType:依据Bean的类型进行主动拆卸
  4. constructor:相似于byType,不过是利用于结构器的参数,如果正好有一个Bean与结构器的参数类型雷同则能够主动拆卸,否则会导致谬误。
  5. autodetect:如果有默认的结构器,这通过constructor的形式进行主动拆卸,否则应用byType的形式进行主动拆卸。

Spring中如何应用注解来配置Bean?有哪些相干的注解?

在启动类上增加@EnableAutoConfiguration或者@SpringBootApplication来开启主动配置,而后应用以下的注解来标注须要由Spring IOC容器进行对象托管的类。

  1. @Component:其余所有类
  2. @Controller:controller控制器
  3. @Service:service业务逻辑层
  4. @Repository:dao数据交互层
    这几个注解的作用其实都是雷同的,都是将类注入到ioc容器中,只是为了不便区别字面上有所不同罢了。

Spring MVC 的工作流程

  1. 客户端的所有申请都叫给前端管制dispatcherServlet来解决,它会负责调用零碎的其余模块来真正解决用户的申请。
  2. 前端控制器DispatcherServlet收到申请后,将依据申请的信息以及HandlerMapping的配置找到解决该申请的对应Handler处理器。
  3. spring会通过HandlerAdapter对该处理器进行封装,而后用对立的接口对各种Handler中的办法进行调用。
  4. Handler实现对用户申请的解决后,会返回一个ModelAndView对象给前端控制器DispatcherServlet。
  5. DispatcherServlet借助逻辑视图解析器ViewResolver来解析刚返回失去的ModelAndView对象
  6. 最初拿到真正的视图对象,浏览器对模型数据进行渲染
  7. 客户端失去响应,可能是一个一般的html页面,也可能是xml或者是JSON字符串,还能够是一张图片或者PDF文件。

ApplicationContext通常的实现是什么?

  • FlieSystemXmlApplciationContext: 此容器从一个XML文件中加载bean是的定义,XML bean配置文件的全路径名必须提供给他的构造函数。
  • ClassPathXmlApplicationContext: 此容器也从一个XML文件中加载Beans的定义,这里,你须要正确设置classpath,因为这个容器将在classpath外面找到bean配置。
  • WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个web利用的所有bean。

Bean工厂和APlication contexts有什么区别?

  • 相同点:两者都是通过xml配置文件加载bean
  • 不同点:applicationContext相比于BeanFactory,提供了更多的扩大性能。BeanFactory是提早加载,如果Bean的某一个属性没有注入,BeanFactory加载后,直至第一次应用调用getBean办法才会抛出异样。而ApplicationContext则在初始化本身就进行了效验,这样有利于查看说依赖属性是否注入。所以通常状况下咱们抉择应用ApplicationContext。

spring有几种依赖注入形式

  1. 变量注入

    • 间接在变量下面应用@Autowired的既是变量注入
    • 长处就是注入形式简略,十分简洁。
    • 毛病:注入的对象不能用final润饰;可能会导致循环依赖的呈现;对于IOC容器以外的环境,除了应用反射来提供它须要的依赖,无奈复用该实现类;
  2. 结构器注入

    • 显式注明必须强制注入,通过强制指明依赖注入来保障这个类的运行,防止出现空指针异样。
    • 注入对象能够应用final润饰。
    • 非IOC容器环境也能够应用new实例化该类的对象。
    • 防止了循环依赖,如果真的存在循环依赖,spring我的项目启动的时候就会报错。
    • 毛病就是当咱们须要注入的对象过多的时候,构造函数的代码会显得十分的臃肿。
  3. setter办法注入

    • 依赖注入中应用的依赖是可选的,抉择依赖的意思是注入的依赖是能够为NULL。
    • 容许在类结构实现后从新注入
    • 毛病就是注入对象不能应用final润饰

    总结:如果注入的属性是必选的属性,则通过结构器注入的形式;如果注入的属性是可选的,则通过setter注入的形式;至于变量注入,不倡议应用,尽管很省劲。

什么是spring beans?

咱们的spring应用程序就是由一个个spring beans组成的,它们通过注解或者xml配置文件的形式定义,而后注入到的IOC容器中,由IOC容器治理整个生命周期。

spring中的bean是线程平安的吗?

首先spring IOC容器自身并没有提供线程安全策略,因而咱们对于bean的线程平安问题,咱们须要联合具体的bean作用域来说:

  1. singleton:单例bean,不会创立新的bean,所有的线程都专用一个bean对象,因而可能会存在线程平安问题。
  2. prototype:原型bean,因为每次都会创立一个bean对象,所以不会呈现线程平安问题。
    实际上大部分理论spring bean都是无状态的,即无需进行数据保留操作,只是进行数据的查问。这个时候即便是单例bean也是线程平安的,然而如果要进行数据保留的一些操作,这个时候就须要咱们开发者本人对线程平安进行一些保障操作了。例如将singleton变为prototype

Spring如何解决线程并发问题?

  1. 个别状况下,只有无状态的bean才能够再多线程环境下共享,在Spring中,绝大部分bean都是以singleton申明的作用域,所以可能存在线程平安问题。所以咱们能够采纳ThreadLocal和线程同步机制来解决线程平安问题。
  2. ThreadLocal采纳了空间换工夫的做法,为每一个线程提供一个独立的变量正本,从而隔离了多个线程对于对一个变量资源的拜访。
  3. 而线程同步机制则是对于可能存在线程平安问题的资源进行加锁,不同的线程在拜访加锁资源之前都须要获取锁资源,没有获取到的须要进行期待。这样就保障了同时只有一个线程对资源进行操作,也就解决了多线程资源并发的问题。然而因为要期待锁资源,所以是一种“工夫换空间”的做法。

主动拆卸有哪些局限性?

  1. 重写:你仍须要和配置来定义依赖,意味着重要重写主动拆卸。
  2. 根本数据类型:你不能主动拆卸简略的属性,如根本数据类型,String字符串和类。
  3. 含糊个性:主动状态不如显示拆卸准确,如果有可能还是倡议应用显示拆卸。

你可始终了spring中注入一个null和一个空字符串嘛?

能够

@Autowired和@Resource之间有什么区别?

  1. @Autowired默认是依照类型进行拆卸注入的,、
  2. 而@Resource默认是依照名称来拆卸注入的,只有当找不到名称匹配的bean才会依照类型来拆卸。

@Qualifier注解有什么用?

用来配合@Autowired注解更加精准的指定拆卸哪个bean,因为@AutorWried是依照类型进行拆卸的,如果有多个同类型的bean须要被拆卸,单单应用@AutoWried注解是不行的,须要通过增加@Qualifier注解来指定name拆卸。

@RequestMapping注解有什么用?

@RequestMapping注解用于将特定HTTP申请办法映射到将解决响应申请的控制器重的特定类和特定办法。

Spring 事务的实质

spring 事务的实质其实就是对数据库事务的反对,如果没有数据库的事务反对,spring是无奈提供事务性能的,真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

说一下Spring的事务流传行为

spring事务的流传行为就是说,当多个事务同时存在的时候,spring如何解决这些事务的行为:

  1. propagation_required:如果以后没有事务,就创立一个新事务,如果以后存在事务,就退出该事务,该设置是最罕用的设置。
  2. propagation_supports:反对以后事务,如果以后存在事务,就退出该事务,如果以后不存在事务,就以非事务运行。
  3. propagation_mandatory:反对以后事务,如果以后存在事务,就退出该事务,如果以后不存在事务,就抛出异样。
  4. propagatin_requires_new:创立新的事务,无论以后是否曾经存在事务,都会创立新的事务。
  5. propagation_not_supported:以非事务形式执行操作,如果以后存在事务,就把以后事务挂起。
  6. propagation_never:以非事务形式执行,如果以后存在事务,则抛出异样。
  7. propagation_nested:如果以后存在事务,则在嵌套事务内执行。如果以后没有事务,这创立一个新的事务。

说一下 spring 的事务隔离?

spring 有五大隔离级别,默认值为 ISOLATION_DEFAULT(应用数据库的设置),其余四个隔离级别和数据库的隔离级别统一:

  1. ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
  2. SOLATION_READ_UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其余事务读取(会呈现幻读、脏读、不可反复读);
  3. ISOLATION_READ_COMMITTED:提交读,一个事务提交后能力被其余事务读取到(会造成幻读、不可反复读),SQL server 的默认级别;
  4. ISOLATION_REPEATABLE_READ:可反复读,保障屡次读取同一个数据时,其值都和事务开始时候的内容是统一,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别;
  5. ISOLATION_SERIALIZABLE:序列化,代价最高最牢靠的隔离级别,该隔离级别能避免脏读、不可反复读、幻读。
脏读 :示意一个事务可能读取另一个事务中还未提交的数据。比方,某个事务尝试插入记录 A,此时该事务还未提交,而后另一个事务尝试读取到了记录 A。
不可反复读 :是指在一个事务内,屡次读同一数据后果不统一。
幻读 :是指在一个事务内,屡次读取的数据条数不统一。

Spring AOP and AspectJ AOP 有什么区别?AOP都有哪些实现形式?

AOP实现的关键在于代理模式,AOP代理模式次要分为动态代理和动静代理。动态代理代表就为AspectJ,而动静代理则以Spring AOP为代表。

  • AspectJ 是动态代理的加强,所谓动态代理,就是AOP框架会在编译阶段生成AOP代理类,因而也称为编译时加强,他会在编译阶段将AscpectJ(切面)织入到Java字节码中,运行的时候就是加强之后的aop对象。
  • spring aop应用的是动静代词,所谓的动静代词就是说AOP框架不会去批改字节码,而是每次运行时在内存中长期为办法生成一个aop对象,这个aop对象蕴含了对象的全副办法,并且在特定的切点还做了加强解决,并回调原对象的办法。

JDK动静代理和CGLIB动静代理的区别?

  • JDK代理只能对实现接口的类生成代理;CGLib是针对类实现代理,对指定的类生成一个子类,并笼罩其中的办法,这种通过继承类的实现形式,不能代理final润饰的类。
  • JDK代理应用的是反射机制实现aop的动静代理,CGLib代理应用字节码解决框架ASM,通过批改字节码生成子类。所以jdk动静代理的形式创立代理对象效率较高,执行效率较低,CGLib创立效率较低,执行效率高。
  • JDK动静代理机制是委托机制,具体说动静实现接口类,在动静生成的实现类外面委托hanlder去调用原始实现类办法,CGLib则应用的继承机制,具体说被代理类和代理类是继承关系,所以代理类是能够赋值给被代理类的,如果被代理类有接口,那么代理类也能够赋值给接口。

动静代理和动静代理的区别?

动态代理与动静代理区别在于生成AOP代理对象的机会不同,动态代理在字节码生成的时候就曾经存在代理类了,而动静代理切实字节码文件生成后,内存中动静增加代理对象的。