Spring核心部分,JAVA高级开发程序员必会面试必备

spring的模块有哪些?

Spring Core:基础,可以说Spring其他所有的功能都依赖于该类库。主要提供IOC和DI功能。
Spring AOP:提供面向方面的编程实现。
Spring JDBC:Java数据库连接。
Spring JMS:Java消息服务。
Spring ORM:用于支持Hibernate等ORM工具。
Spring Web:为创建Web应用程序提供支持。
Spring Test:提供了对JUnit和TestNG测试的支持。
spring tx:事务

说下你对spring的理解?

1.Spring框架帮我们管理对象及其依赖关系
2.是基于POJO的轻量级和最小侵入性编程
3.通过依赖注入进行控制反转
4.通过依赖注入和面向接口来松耦合

对spring ioc的理解和使用?

以前没有spring的时候,我们需要得到一个对象,都是自己主动去new一个对象,然后通过set方法给对象注入属性,但是这种动作其实是一个重复的动作,所以spring提供ioc的容器解决方案,在容器启动的时候就把许多需要实例化和属性注入的bean都提前做好并放入到一个map中存储起来。这就是控制反转,原来的控制全在用户,现在的控制权完全交给了容器,在bean实例化后,通过反射对属性进行依赖注入
有两种使用方式,一种是xml的方式,一种是注解的方式。
xml的加载方式,首先在spring的xml中通过bean标签配置我们需要注入的bean,当扫描到所有的bean后,首先把bean包装成BeanDe送nition,放入到list中,然后循环这个list去创建bean,创建bean的步骤为实例化->属性注入->初始化->aop,然后最终放入到spring的一级缓存中保存起来。注解方式是通过在类上面加上spring的注解去扫描,比如controller,service等,后续步骤和xml基本一样。

Bean的生命周期?那你有如何使用这些扩展的步骤呢?

spring的bean的生命周期主要是创建bean的过程,一个bean的生命周期主要是4个步骤,实例化,属性注入,初始化,销毁,但是对于一些复杂的bean的创建,spring会在bean的生命周期中开放很多的接口,可以让你加载bean的时候对bean做一些改变,因此spring的bean的生命周期总共有以下几步:
首先在spring中有一些特殊的bean会介入到其他bean的声明周期当中去,所以一个普通的bean的声明周期为:

  1. 实现了BeanFactoryPostProcessor接口的bean,在加载其他的bean的时候,也会调用这个bean的postProcessBeanFactory方法,可以在这个步骤去对bean中的属性去赋值。设置年龄初始化18等等。
  2. 实现了InstantiationAwareBeanPostProcessor接口的bean,会在实例化bean之前调用
    postProcessBeforeInstantiation方法
  3. 然后在对bean进行实例化
  4. 对bean进行属性注入
  5. 对bean进行初始化,在初始化中,包含了以下几个步骤:
    1)实现了BeanFactoryAware接口,会先调用setBeanFactory方法
    2)实现了BeanNameAware接口,会先调用setBeanName方法
    3)实现了BeanPostProcessor接口,会先调用 postProcessBeforeInitialization方法
    4)实现了InitializingBean接口,会调用afterPropertiesSet方法
    5)init-method方法调用
    6)然后在进行aop后置处理,通过实现BeanPostProcessor接口,在postProcessAfterInitialization方法中进行动态代理
  6. 销毁
    当然还有一些其他的步骤,在此就不一一列举了,bean的生命周期总共有18步。
    第一个:比如要继承spring的时候,把bean交给spring管理
    第二个:dubbo源码跟spring整合就完全的使用到了spring扩展点
    第三个:自己开发中可以实现spring提供的这些扩展点

Bean是如何创建的?这个容器的数据结构是什么样子的

在spring中,万物都是bean对象,每一个对象都可以封装成BeanDefinition,然后去生成bean对象。
所以首先第一步,spring要找到哪些bean需要实例化,第一种是xml的方式,如果需要实例化bean就在xml中配置bean标签,找到所有需要创建的bean,第二种注解方式,扫描所有添加了spring注解的bean,把所有的bean封装成一个BeanDe送nition放入一个list.
第二步,循环list,通过BeanDe送nition中的类全名称,通过反射进行实例化,属性注入,如果还有一个初始化的动作,也可以在属性注入后做,比如:init-method方法,比如实现了InitializingBean这个接口,然后在初始化的时候自动调用afterPropertiesSet该方法,我们可以在这个里面对bean做其他的操作,如果bean需要被代理,则通过后置通知,去生成代理的bean,如果bean实现了接口就使用jdk代理,如果没有实现就使用cglib,如果配置的优先级,则优先使用cglib.
第三步,完成后就将bean放入到spring的一级容器中。
数组+链表+红黑树

spring注入bean的方式有哪些?

1.通过@Con送guration+@Bean的方式注入
2.通过实现ImportBeanDe送nitionRegistrar接口可以往容器中注入BeanDe送nition,从而注入bean
3.通过实现ImportSelector接口可以往spring容器中批量注入Bean
4.通过实现FactoryBean接口可以往Spring容器中自定义Bean
5.@Componet + @ComponentScan
6.xml方式

Spring常用的设计模式有哪些?

  1. 工厂设计模式:Spring使用工厂模式可以通过BeanFactory或ApplicationContext创建bean对象。
    BeanFactory :延迟注入(使用到某个 bean 的时候才会注入),相比于ApplicationContext 来说会占用更少的内存,
    程序启动速度更快。
    ApplicationContext :容器启动的时候,不管你用没用到,一次性创建所有 bean 。BeanFactory 仅提供了最基
    本的依赖注入支持,ApplicationContext 扩展了 BeanFactory ,除了有BeanFactory的功能还有额外更多功能,所
    以一般开发人员使用ApplicationContext会更多
  2. 单例设计模式:Spring中bean的默认作用域就是singleton。spring的一级缓存就是使用的容器式单例
  3. 代理设计模式:Spring AOP就是基于动态代理的。如果要代理的对象,实现了某个接口,那么Spring AOP会
    使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用JDK Proxy去进行代理了,这时候Spring AOP会使用Cglib,这时候Spring AOP会使用Cglib生成一个被代理对象的子类来作为代理。
  4. 模板方法设计模式:Spring中jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,
    它们就使用到模板模式。
  5. 观察者设计模式:Spring事件驱动模型就是观察者模式很经典的应用。
    spring的事件流程:
    1)定义一个事件: 实现一个继承自 ApplicationEvent,并且写相应的构造函数
    2)定义一个事件监听者:实现 ApplicationListener 接口,重写 onApplicationEvent() 方法
    3)使用事件发布者发布消息: 可以通过 ApplicationEventPublisher 的 publishEvent() 方法发布消息
  6. 适配器设计模式:适配器模式使得接口不兼容的那些类可以一起工作,其别名为包装器
    在Spring MVC中,DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler,解析到对应
    的Handler(也就是我们常说的Controller控制器)后,开始由HandlerAdapter适配器处理
    6.装饰者设计模式:装饰者设计模式可以动态地给对象增加些额外的属性或行为。相比于使用继承,装饰者模式更
    加灵活
    Spring 中配置DataSource的时候,DataSource可能是不同的数据库和数据源。我们能否根据客户的需求在少修改
    原有类的代码下切换不同的数据源?这个时候据需要用到装饰者模式。
    7.策略设计模式:Spring 框架的资源访问接口就是基于策略设计模式实现的
    23种基本都用了

spring是如何解决循环依赖的?

1.构造函数循环依赖(无法解决)
首先要解决循环依赖就是要先实例化,然后放入三级缓存暴露出来,那么如果是构造函数这一步循环依赖,实例化的时候就会产生无限递归创建,所以不能解决,如果是延迟加载的话可以解决(另当别论)
2.setter方式的多例的循环依赖(无法解决)
如果是多例的,在容器初始化的时候,不会去创建,所以早期没有放入到三级缓存中暴露出来,所以无法解决循环依赖,会报错
3.setter方式的单例循环依赖(A依赖B,B依赖A)
A与B循环依赖,都要被代理的情况
1.A实例化->A放入三级缓存->依赖注入B->B实例化->B放入三级缓存->依赖注入a->去三级缓存拿a的代理
->把代理的A放入二级->返回a的代理注入到B->b初始化->走后置通知获得代理b->B的代理放入一级缓存、
->原生a依赖注入b->A初始化->后置通知,不走代理返回原生A->再偷天换日->放入一级缓存
4.dependOn

Spring Aop的理解和使用?

Aop面向切面编程,在spring中,通过配置切面类和切点,切面类中主要有前置通知方法,后置通知方法,异常通知方法以及环绕通知方法,切面类中的方法的逻辑就是你要织入代码的逻辑,然后你需要判断哪些类需要进行前面切面,所以就要配置切入点,可以使用xml方式,也可以使用注解的方法。
实现方式主要是通过动态代理给目标类生成代理对象,如果目标类实现了接口就使用jdk代理,如果没有实现接口
使用cglib代理,如果配置了优先级,则默认使用cglib代理。在spring容器启动后,就会去扫描哪些需要进行aop的类,这些类有哪些切面(切面是可以配置多个的),然后给目标类的每个方法都绑定一个相应的执行链,并放入到一个map中,当你调用时,会走代理类,然后通过索引加递归的方式去调用切面类前置通知方法,目标类方法,后置通知方法这样的顺序去调用。
使用:可以拦截目标类,在方法的前后织入日志打印逻辑,包括spring事务开启也是使用的aop,还有动态数据源切换等场景都是可以使用aop。如果配置多个切面,则要指定执行顺序,通过设置sort的大小来指定,sort值越小,越先执行,越后结束,sort值越大,越后执行,越先结束,就相当于一个同心圆。事务sort值默认是int类型的最大值。

spring中的AOP是在DI之前还是之后?

1.一个正常的bean:AOP在DI之后
2.如果有循环依赖:AOP在DI之间
对于spring中的bean的懒加载如何实现
1.如果想让单例的bean懒加载,就要加@Lazy注解
2.多例的bean在容器初始化本来就是懒加载的,只有在调用的时候去实例化,所以加@Lazy有没有意义

spring中声明式事务注解中的参数

1.propagation传播机制
2.isolation隔离级别
3.timeout超时时间,如果共用一个事务,只有之前的事务设置的timeout有效
4.rollbackFor回滚异常
5.noRollbackFor不回滚异常

Mysql事务的特点

事务应该具有 4 个属性:原子性、一致性、隔离性、持久性
原子性(Automicity)
一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(Consistency)
事务必须是使数据库从一个一致性状态变到另一个一致性状态。
一致性与原子性是密切相关的。
隔离性(Isolation)
一个事务的执行不能被其他事务干扰。
即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(Durability)
持久性也称永久性(Permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

spring的事务失效场景

1.非public方法 事务的实现原理是代理增强,非public不能进行代理增强,不能进行JDK或者CGLIB代理
2.调用本类的方法 (调用methodC方法)
3.抛出捕捉的非RuntimeException,如果想要捕捉所有异常(rollbackFor = {Exception.class})
或者指定@Transactional(rollbackFor = {RuntimeException.class,ClassNotFoundException.class},propagation
=Propagation.REQUIRED) 多个异常类
4.我们知道事务就是依赖于数据库的,所以数据库不支持肯定也是失效的!!比如myIsam
5.多线程下事务会失效,因为ThreadLocal的数据只在当前线程中有效

对spring事务的理解?

spring的事务开启方式有两种,一个是声明式事务,一个是编程式事务,声明式事务是通过添加Transaction注解
的方式开启事务,一般加在类或者方法上,事务控制粒度比较大,但使用上比较方便,编程式事务通过TransactionTemplate,控制事务的粒度小,但是代码侵入性比较强。使用spring aop实现。

spring事务提供了7中传播机制:

  1. REQUIRED(必须的):是默认的传播机制,如果B方法中调用A,如果B中有事务,则A无论是否开启事务都会用B
    的事务,任何地方出现异常A和B都回滚
  2. REQUIRES_NEW(需要新的):每次都会开启一个新的事务,外面事务回滚,里面事务不会回滚
  3. SUPPORTS(1): 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行,完全依赖最外层事务
  4. MANDATORY(强制性的):必须运行在事务里面
  5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
  6. NEVER:以非事务方式执行,如果当前存在事务,则抛出异常
  7. NESTED:开启新事务,提交事务依赖于外层事务,如果外层事务回滚,则里面事务也回滚

spring事务还提供了四种隔离级别:

  1. DEFAULT(-1):数据库默认的隔离级别
  2. READ_UNCOMMITTED(1):读未提交 ru,会导致脏读
  3. READ_COMMITTED(2):读已提交 rc 避免脏读,允许不可重复读和幻读
  4. REPEATABLE_READ(4):可重复读 rr 避免脏读,不可重复读,允许幻读,innodb存储引擎解决了幻读
  5. SERIALIZABLE:串行化
    从上到下,隔离级别越来越高,并发性能就越来越差,spring事务的本质还是数据库的事务,如果数据库不支持事
    务,spring的事务也就没有了意义

springmvc的流程?

1.用户发送请求至前端控制器DispatcherServlet;
2.DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handler;
3.处理器映射器根据请求url找到具体的处理器Handler,生成处理器对象及处理器拦截器(如果有则生成),一并返
回给DispatcherServlet;
4.DispatcherServlet 调用 HandlerAdapter处理器适配器,请求执行Handler;
5.HandlerAdapter 经过适配调用 具体处理器进行处理业务逻辑;
6.Handler执行完成返回ModelAndView;
7.HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
8.DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
9.ViewResolver解析后返回具体View;
10.DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
11.DispatcherServlet响应用户。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值