spring 面试题

目录

1、IOC (inversion of controller)

2、spring 有什么

3、AOP (Aspect-Oriented Programming)

        1、用静态代理方式处理业务:转钱、发钱、查看 之前做校验。操作之后打印统一日志。

        2、用JDK动态代理实现上面的功能增强。

        3、JDK动态代理必须要有接口, 但如果要代理一个没有接口的类该怎么办呢? 这时我们可以使用CGLIB动态代理.

        4、CGLIB动态代理的原理 , 使用CGLIB 动态代理实现上面。

    模拟spring AOP :

    AspectJ AOP :

            AspectJ  的使用

4、Spring AOP和AspectJ AOP有什么区别?

5、Spring中的bean的作用域有哪些?(scope)

        springboot 、spring 设置bean 作用域

6、spring 的bean 是什么    

8、Spring中的单例bean的线程安全问题了解吗?

9、spring bean 的生命周期

10、对于Spring MVC的了解

    请求spring MVC 的流程:

11、Spring框架中用到了哪些设计模式

12、@Component和@Bean的区别是什么

13、将一个类声明为Spring的bean的注解有哪些?

14、Spring事务管理的方式有几种?

15、Spring事务中的隔离级别有哪几种?

ACID :

举个简单的例子理解事务四点特性

16、脏读、不可重复读、幻读?

        MVCC :

17、spring事务与数据库事务

18、spring 事务的使用和原理

    spring事务为什么不能保证数据一致性和业务逻辑正确性:

17、mysql 数据库的事务隔离级别

18、Spring事务中有哪几种事务传播行为?

    支持当前事务的情况:

    不支持当前事务的情况:

19、在springboot中 事务是怎么实现和使用的

20、spring 中事务是如何实现和使用的

回答 spring (spring boot) 事务是怎么实现的

21、spring 事务 特性 (ACID) 


spring 面试题:

1、IOC (inversion of controller)

    控制反转、设计思想、IOC容器创建对象、IOC容器是存放各种对象的map

    对象依赖关系给IOC容器管理、完成注入、用注解或者配置、简化开发

    IOC初始化过程。?

    

2、spring 有什么

    核心:DI(依赖注入)、AOP、事件(events)

    测试:模拟对象、testContext框架、SpringMVC测试、WebTestClient

    数据访问:事务、dao支持、jdbc、ORM

    Web支持:spring MVC 、servlet、 webSocket/

    集成:远程处理、JMS、电子邮件、任务、调度、缓存、JCA、JMX

    

3、AOP (Aspect-Oriented Programming)

    面向切面编程

    封装非业务模块、业务需要调用

    eg:事务处理、日志管理、权限控制

    低耦合、少重复代码、可拓展、可维护

    

    资料:

    1、Spring AOP原理之动态代理: Spring AOP原理之动态代理_Tyshawn的博客-CSDN博客_spring 动态代理

    2、spring的15个经典面试题: spring的15个经典面试题 - yanggb - 博客园

  

问题:

        1、用静态代理方式处理业务:转钱、发钱、查看 之前做校验。操作之后打印统一日志。

        2、用JDK动态代理实现上面的功能增强。

        3、JDK动态代理必须要有接口, 但如果要代理一个没有接口的类该怎么办呢? 这时我们可以使用CGLIB动态代理.

        4、CGLIB动态代理的原理 , 使用CGLIB 动态代理实现上面。

                CGLIB动态代理的原理是生成目标类的子类, 这个子类对象就是代理对象, 代理对象是被增强过的.

                注意: 不管有没有接口都可以使用CGLIB动态代理, 而不是只有在无接口的情况下才能使用.

    AOP基于动态代理(Proxy)

    静态代理:  为每一个业务增强提供一个代理类,有代理类类创建对象

    动态代理:  没有代理类,代理对象有代理生成工具动态生成。

    

    jdk动态代理:  InvocationHandler 实现这个接口,重写invoke方法,在这个方法里面增强。

    

    CGLIB动态代理:  JDK动态代理必须要有接口,如果代理类没有接口就用CGLIB动态代理。

        写法:实现MethodInterceptor ,重写intercept方法

    CGLIB动态代理原理:  CGLIB动态代理的原理是生成目标类的子类, 这个子类对象就是代理对象, 在子类里面做增强。

    

    模拟spring AOP :

        1、抽象类实现接口MethodInterceptor,模板方法的设计,有开始, 结束, 异常, 前置增强, 后置增强提供了默认实现。设计切入点方法。

        2、切面类继承抽象类,重写切入点,重写需要用到的地方。

        3、代理工厂类创建代理,执行业务

    

    AspectJ AOP :

          spring继承了AspectJ, 是java生态中比较完整的AOP框架。

            AspectJ  的使用

@Aspect 注解使用详解_fz13768884254的博客-CSDN博客

@AspectJ切点函数详解_V5放纵丶的博客-CSDN博客

    Spring AOP 使用:  把通用功能抽象出来,用到的地方直接使用。简化代码、拓展方便、提高了可维护性和可拓展性。(日志功能、事务管理、权限管理等都用到AOP)

    

4、Spring AOP和AspectJ AOP有什么区别?

    Spring AOP是属于运行时增强,而AspectJ是编译时增强。Spring AOP基于代理(Proxying),而AspectJ基于字节码操作(Bytecode Manipulation)。

    Spring AOP已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。AspectJ相比于Spring AOP功能更加强大,但是Spring AOP相对来说更简单。

    如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择AspectJ,它比SpringAOP快很多。

文章:

AOP的两种实现-Spring AOP以及AspectJ [AOP] 2. AOP的两种实现-Spring AOP以及AspectJ_不忘初心,好好沉淀-CSDN博客

    

5、Spring中的bean的作用域有哪些?(scope)

    1.singleton:唯一bean实例,Spring中的bean默认都是单例的。

    2.prototype:每次请求都会创建一个新的bean实例。

    3.request:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。

    4.session:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP session内有效。

    5.global-session:全局session作用域,仅仅在基于Portlet的Web应用中才有意义,Spring5中已经没有了。Portlet是能够生成语义代码(例如HTML)片段的小型Java Web插件。它们基于Portlet容器,可以像Servlet一样处理HTTP请求。但是与Servlet不同,每个Portlet都有不同的会话。

        springboot 、spring 设置bean 作用域

<bean id="xmlinstance" class="com.demo.model.XMLInstance" scope="singleton">
@Scope("singleton")
@Component
public class SingleScopeTest {
}

6、spring 的bean 是什么    

    

    

7、spring 的bean

8、Spring中的单例bean的线程安全问题了解吗?

    大部分时候我们并没有在系统中使用多线程,所以很少有人会关注这个问题。单例bean存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。

    有两种常见的解决方案:

    1.在bean对象中尽量避免定义可变的成员变量(不太现实)。

    2.在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中(推荐的一种方式)。

    

9、spring bean 的生命周期

    1.Bean容器找到配置文件中Spring Bean的定义。

    2.Bean容器利用Java Reflection API创建一个Bean的实例。

    3.如果涉及到一些属性值,利用set()方法设置一些属性值。

    4.如果Bean实现了BeanNameAware接口,调用setBeanName()方法,传入Bean的名字。

    5.如果Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。

    6.如果Bean实现了BeanFactoryAware接口,调用setBeanClassFacotory()方法,传入ClassLoader对象的实例。

    7.与上面的类似,如果实现了其他*Aware接口,就调用相应的方法。

    8.如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessBeforeInitialization()方法。

    9.如果Bean实现了InitializingBean接口,执行afeterPropertiesSet()方法。

    10.如果Bean在配置文件中的定义包含init-method属性,执行指定的方法。

    11.如果有和加载这个Bean的Spring容器相关的BeanPostProcess对象,执行postProcessAfterInitialization()方法。

    12.当要销毁Bean的时候,如果Bean实现了DisposableBean接口,执行destroy()方法。

    13.当要销毁Bean的时候,如果Bean在配置文件中的定义包含destroy-method属性,执行指定的方法。

    

通俗解释:

    实例化bean对象 -> 设置对象属性 -> 检查Aware相关接口并设置相关依赖 ->

    BeanPostProcessor前置设置 -> 检查是否是InitializingBean以决定是否调用afterPropertiesSet方法 ->

    检查是否配置有自定义的init-method -> BeanPostProcessor后置处理 ->

    注册必要的Destruction(销毁)相关回调接口 -> 使用中 ->

    是否实现DispostableBean接口 -> 是否配置有自定义的destroy方法

    

    

10、对于Spring MVC的了解

    请求spring MVC 的流程:

    DespatcherServlet、 handlerMapping 、handler 、 HandlerAdapter 、ModelAndView、 Model、View、 ViewResolver

    下面流程内容只是其中一种。但包含了最重要的流程。

    1.客户端(浏览器)发送请求,直接请求到DispatcherServlet。

    2.DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。

    3.解析到对应的Handler(也就是我们平常说的Controller控制器)。

    4.HandlerAdapter会根据Handler来调用真正的处理器来处理请求和执行相对应的业务逻辑。

    5.处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是逻辑上的View。

    6.ViewResolver会根据逻辑View去查找实际的View。

    7.DispatcherServlet把返回的Model传给View(视图渲染)。

    8.把View返回给请求者(浏览器)。

    

    

11、Spring框架中用到了哪些设计模式

    DI、IOC、AOP、bean默认、jdbcTemplate、连接多库、驱动模型、通知(advice)、controller

    

    1.工厂设计模式:Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。

    2.代理设计模式:Spring AOP功能的实现。

    3.单例设计模式:Spring中的bean默认都是单例的。

    4.模板方法模式:Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,它们就使用到了模板模式。

    5.包装器设计模式:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。

    6.观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。

    7.适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。

    

    

12、@Component和@Bean的区别是什么

    1.作用对象不同。@Component注解作用于类,而@Bean注解作用于方法。

    2.@Component注解通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用@ComponentScan注解定义要扫描的路径)。@Bean注解通常是在标有该注解的方法中定义产生这个bean,告诉Spring这是某个类的实例,当我需要用它的时候还给我。

    3.@Bean注解比@Component注解的自定义性更强,而且很多地方只能通过@Bean注解来注册bean。比如当引用第三方库的类需要装配到Spring容器的时候,就只能通过@Bean注解来实现。

    

   

   @Configuration
    public class AppConfig {
        @Bean
        public TransferService transferService() {
            return new TransferServiceImpl();
        }
    }
    
    <beans>
        <bean id="transferService" class="com.yanggb.TransferServiceImpl"/>
    </beans>
    
    @Bean
    public OneService getService(status) {
        case (status)  {
            when 1:
                    return new serviceImpl1();
            when 2:
                    return new serviceImpl2();
            when 3:
                    return new serviceImpl3();
        }
    }

    

13、将一个类声明为Spring的bean的注解有哪些?

    我们一般使用@Autowired注解去自动装配bean。而想要把一个类标识为可以用@Autowired注解自动装配的bean,可以采用以下的注解实现:

    1.@Component注解。通用的注解,可标注任意类为Spring组件。如果一个Bean不知道属于哪一个层,可以使用@Component注解标注。

    2.@Repository注解。对应持久层,即Dao层,主要用于数据库相关操作。

    3.@Service注解。对应服务层,即Service层,主要涉及一些复杂的逻辑,需要用到Dao层(注入)。

    4.@Controller注解。对应Spring MVC的控制层,即Controller层,主要用于接受用户请求并调用Service层的方法返回数据给前端页面。

    

    

14、Spring事务管理的方式有几种?

    1.编程式事务:在代码中硬编码(不推荐使用)。

    2.声明式事务:在配置文件中配置(推荐使用),分为基于XML的声明式事务和基于注解的声明式事务。

15、Spring事务中的隔离级别有哪几种?

    在TransactionDefinition接口中定义了五个表示隔离级别的常量:

    isolation_default:(默认)使用后端数据库默认的隔离级别,Mysql默认采用的repeatable_read(可重复读)隔离级别;Oracle默认采用的read_committed(读已提交)隔离级别。

    read_uncommitted:(读未提交)最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

    read_committed:(读提交)允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。   读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。

    repeatable_read:(重复读)对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。  重复读:同一个事务里面的相同查询,是一样的。

    serializable:(序列化、串行化)最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

    

ACID :

        谈到事务一般都是以下四点特性

原子性(Atomicity)
        原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
        事务前后数据的完整性必须保持一致。
隔离性(Isolation)
        事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
        持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

举个简单的例子理解事务四点特性

    

16、脏读、不可重复读、幻读?

    幻读:insert 操作

        事务A 按照一定条件进行数据读取, 期间事务B 插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B 新插入的数据 称为幻读

    不可重复读:update操作, 了一个事务范围内两个相同的查询却返回了不同数据

    脏读:读到未提交的数据。读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。

        MVCC :

17、spring事务与数据库事务

    spring事务本质上使用数据库事务,而数据库事务本质上使用数据库锁,所以spring事务本质上使用数据库锁,开启spring事务意味着使用数据库锁;

    

    

18、spring 事务的使用和原理

    (文档:spring的事务是什么?与数据库的事务是否一样 - 南哥的天下 - 博客园

    spring事务:

    spring事务本质上使用数据库事务,而数据库事务本质上使用数据库锁,所以spring事务本质上使用数据库锁,开启spring事务意味着使用数据库锁;

    那么事务的隔离级别与锁有什么关系呢?本人认为事务的隔离级别是通过锁的机制实现的,事务的隔离级别是在数据库开发上根据业务逻辑的实际需要定义的一组锁的使用策略。当我们将数据库的隔离级别定义为某一级别后如仍不能满足要求,我们可以自定义 sql 的锁来覆盖事务隔离级别默认的锁机制。

    spring事务实际使用AOP拦截注解方法,然后使用动态代理处理事务方法,捕获处理过程中的异常,spring事务其实是把异常交给spring处理;

    spring事务只有捕获到异常才会终止或回滚,如果你在程序中try/catch后自己处理异常而没有throw,那么事务将不会终止或回滚,失去事务本来的作用;

    spring事务会捕获所有的异常,但只会回滚数据库相关的操作,并且只有在声明了rollbackForClassName='Exception'之类的配置才会回滚;

    spring事务会回滚同一事务中的所有数据库操作,本质上是回滚同一数据库连接上的数据库操作;

    spring事务总结:

    spring事务本质上使用数据库锁;

    spring事务只有在方法执行过程中出现异常才会回滚,并且只回滚数据库相关的操作;

    对象锁和spring事务的对比:

    对象锁可以保证数据一致性和业务逻辑正确性,但不能保证并发性;

    spring事务不能严格保证数据一致性和业务逻辑正确性,但具有较好的并发性,因为只锁数据库行数据;

    建议:

    如果只有insert操作,可以使用事务;

    如果涉及update操作但不涉及其他业务逻辑,可以保守使用事务;

    如果涉及update操作及其他业务逻辑,慎用事务,

    并且数据库查询跟数据库更新之间尽量间隔较短,中间不宜插入太多其他逻辑,减少数据一致性的风险;

    对数据一致性要求不高的情况下可以使用事务结合乐观锁,否则建议用锁;

    spring事务为什么不能保证数据一致性和业务逻辑正确性:

        1.如果事务方法抛异常,此时会回滚数据库操作,但已经执行的其他方法不会回滚,因此无法保证业务逻辑正确性;

        2.即使事务方法不抛异常,也不能保证数据一致性(因为事务接口里的数据库操作在整个接口逻辑执行结束后才提交到数据库,在接口最后提交到数据库的前后很有可能带来数据一致性的问题),从而不能保证业务逻辑正确性;

17、mysql 数据库的事务隔离级别

    

    

18、Spring事务中有哪几种事务传播行为?

    在TransactionDefinition接口中定义了八个表示事务传播行为的常量。

    支持当前事务的情况:

    PROPAGATION_REQUIRED:(required)如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

    PROPAGATION_SUPPORTS:(supports) 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

    PROPAGATION_MANDATORY:(mandatory) 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)。

    不支持当前事务的情况:

    PROPAGATION_REQUIRES_NEW:(requires_new) 创建一个新的事务,如果当前存在事务,则把当前事务挂起。

    PROPAGATION_NOT_SUPPORTED:(not_supported) 以非事务方式运行,如果当前存在事务,则把当前事务挂起。

    PROPAGATION_NEVER:(never) 以非事务方式运行,如果当前存在事务,则抛出异常。

    其他情况:

    PROPAGATION_NESTED:(nested) 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于PROPAGATION_REQUIRED。

    @Transaction 默认传播机制:PROPAGATION_REQUIRED

支持当前事务的情况:
        1、required 有加无建
        2、supports 有加无非
        3、mandatory 有加无抛

不支持当前事务情况 ,
        1、required_new 新建有挂
        2、not_supported 非行有挂
        3、never 非行有抛

其他情况
        1、nested 有建嵌套,无建

19、在springboot中 事务是怎么实现和使用的

    ?

    

    

20、spring 中事务是如何实现和使用的

    ?

    并发事务会导致脏读、不可重复读、幻读,为了解决这些问题,数据库中就引入了事务的隔离级别,隔离级别包括:读未提交、读提交、可重复读和串行化。

    Spring中增强了事务的概念,为了解决方法A、方法B和方法C之间的事务关系,引入了事务传播机制的概念。

    Spring中的@Transactional注解的事务实现主要通过TransactionInterceptor拦截器来进行实现的,拦截目标方法,然后判断异常是不是目标异常,如果是目标异常就行进行回滚,否则就进行事务提交。

    最后我们自己通过JDBC结合Spring的AOP自己写了个@MyTransactional的注解,实现了遇到指定异常回滚的功能。

回答 spring (spring boot) 事务是怎么实现的

1. Spring事务底层是基于数据库事务和AOP机制的 

        spring 源码方面:

        借助AOP中动态代理的思想,借助方法拦截器(MethodInterceptor),这里应该是用的cglib代理,在加入事务处理的方法上额外加一些操作。

        基于数据库方面:

        spring事务使用了数据库事务,而数据库事务本质上使用数据库锁,所以spring事务使用了数据库锁,开启spring事务意味着使用数据库锁;

下面是spring 事务的执行流程:

2. 首先对于使用了@Transactional注解的Bean,Spring会创建一个代理对象作为Bean 
3. 当调用代理对象的方法时,会先判断该方法上是否加了@Transactional注解 
4. 如果加了,那么则利用事务管理器创建一个数据库连接 
5. 并且修改数据库连接的autocommit属性为false,禁止此连接的自动提交,这是实现Spring事务非常重要的一步 
6. 然后执行当前方法,方法中会执行sql 
7. 执行完当前方法后,如果没有出现异常就直接提交事务 
8. 如果出现了异常,并且这个异常是需要回滚的就会回滚事务,否则仍然提交事务 
9. Spring事务的隔离级别对应的就是数据库的隔离级别 
10. Spring事务的传播机制是Spring事务自己实现的,也是Spring事务中最复杂的 
11. Spring事务的传播机制是基于数据库连接来做的,一个数据库连接一个事务,如果传播机制配置为需要新开一个事务,那么实际上就是先建立一个数据库连接,在此新数据库连接上执行sql

    

21、spring 事务 特性 (ACID) 

    原 一 隔 持

22、分布式事务    

    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值