【面试】Java最新面试题资深开发-Spring篇(2)

2023-12-16 05:26:28

问题八:Spring原理

接上一篇

  1. 介绍一下Spring的AOP(面向切面编程)是什么,它的主要用途是什么?
  2. Spring中的Bean生命周期是怎样的?可以通过哪些方法来自定义Bean的初始化和销毁过程?
  3. 解释一下Spring中的事务管理。它支持哪些事务传播行为?
介绍一下Spring的AOP(面向切面编程)是什么,它的主要用途是什么?

面向切面编程(AOP)是什么:

面向切面编程(AOP)是一种编程范式,它的主要目的是通过在程序中插入一些横切关注点(cross-cutting concerns),将应用的关注点从业务逻辑中抽离出来,提高代码的模块化和可维护性。在AOP中,切面是包含横切关注点和通知的模块,而通知是在程序执行的特定点上执行的一段代码。

Spring的AOP:

Spring框架提供了强大的AOP支持,使得开发者可以更轻松地实现横切关注点的模块化。Spring的AOP主要通过代理模式来实现,它在运行时动态地生成代理类,将横切关注点织入到目标类的方法中。

AOP的主要用途:

  1. 日志记录: 记录方法的调用时间、参数、返回值等信息,用于调试和性能分析。
  2. 事务管理: 实现声明式事务,将事务的开始、提交、回滚等关注点从业务逻辑中分离出来。
  3. 安全性: 实现对方法的权限检查,确保只有具有特定权限的用户能够调用某些方法。
  4. 缓存管理: 将方法的结果缓存起来,提高方法的执行效率。
  5. 异常处理: 集中处理系统中抛出的异常,进行统一的日志记录或错误处理。
  6. 性能监控: 监控方法的执行时间,找出性能瓶颈。

AOP的关键概念:

  1. 切点(Pointcut): 定义了在程序中哪些地方应用通知。通常使用表达式或者注解来指定切点。
  2. 通知(Advice): 定义了在切点上执行的操作,包括前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、异常通知(AfterThrowing)和环绕通知(Around)等。
  3. 切面(Aspect): 是包含切点和通知的模块,它将通知织入到切点所指定的位置。

示例:

以下是一个简单的AOP示例,用于记录方法的执行时间:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class PerformanceAspect {

    @Around("execution(* com.example.service.*.*(..))")
    public Object measureTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();

        // 执行原始方法
        Object result = joinPoint.proceed();

        long endTime = System.currentTimeMillis();
        System.out.println(joinPoint.getSignature() + " executed in " + (endTime - startTime) + "ms");

        return result;
    }
}

在这个例子中,@Aspect注解表示这是一个切面,@Around注解表示这是一个环绕通知。通过指定切点表达式,这个切面会在所有com.example.service包下的方法执行前后记录执行时间。

AOP的主要用途是通过将横切关注点进行模块化,提高代码的可维护性和可测试性,同时将关注点从业务逻辑中分离出来,使得代码更加清晰。

Spring中的Bean生命周期是怎样的?可以通过哪些方法来自定义Bean的初始化和销毁过程?

Spring中的Bean生命周期包括实例化、属性赋值、初始化、使用、销毁等阶段。在这个过程中,Spring容器通过回调方法来通知Bean生命周期的各个阶段。以下是Spring Bean的生命周期过程:

  1. 实例化(Instantiation): 在这一阶段,Spring容器会根据配置或者注解创建Bean的实例。默认情况下,Spring使用Java的反射机制来实例化Bean。

  2. 属性赋值(Population): 在实例化后,Spring容器会通过依赖注入或者其他配置方式为Bean的属性赋值。

  3. 初始化前回调(Initialization): 在Bean的所有属性都被赋值后,会调用Bean的初始化方法(如果有定义的话)。可以通过实现InitializingBean接口或者在配置文件中使用init-method属性来定义初始化方法。

  4. 初始化(Initialization): 在这一阶段,Bean的初始化方法被调用。这是Bean可以执行自定义初始化逻辑的地方。

  5. 使用(In Use): Bean实例化和初始化完成后,它就可以被应用程序使用了。

  6. 销毁前回调(Destruction): 在Bean被销毁之前,Spring容器会调用Bean的销毁前回调方法。可以通过实现DisposableBean接口或者在配置文件中使用destroy-method属性来定义销毁前回调方法。

  7. 销毁(Destruction): 在这一阶段,Bean的销毁方法被调用。这是Bean可以执行自定义的销毁逻辑的地方。

自定义Bean的初始化和销毁过程的方法:

  1. 实现InitializingBeanDisposableBean接口:

    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    
    public class MyBean implements InitializingBean, DisposableBean {
        // 初始化逻辑
        @Override
        public void afterPropertiesSet() throws Exception {
            // Custom initialization code
        }
    
        // 销毁逻辑
        @Override
        public void destroy() throws Exception {
            // Custom destruction code
        }
    }
    
  2. 使用init-methoddestroy-method属性:

    <bean id="myBean" class="com.example.MyBean" init-method="initMethod" destroy-method="destroyMethod"/>
    
    public class MyBean {
        // 初始化逻辑
        public void initMethod() {
            // Custom initialization code
        }
    
        // 销毁逻辑
        public void destroyMethod() {
            // Custom destruction code
        }
    }
    
  3. 使用JSR-250注解@PostConstruct@PreDestroy

    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    public class MyBean {
        // 初始化逻辑
        @PostConstruct
        public void init() {
            // Custom initialization code
        }
    
        // 销毁逻辑
        @PreDestroy
        public void destroy() {
            // Custom destruction code
        }
    }
    

通过上述方法,开发者可以在Bean的初始化和销毁阶段执行自定义的逻辑,使得Bean的生命周期能够更好地适应应用程序的需求。

解释一下Spring中的事务管理。它支持哪些事务传播行为?

Spring中的事务管理:

Spring框架提供了强大的事务管理支持,使得开发者能够轻松地管理事务的生命周期、隔离级别、传播行为等方面的细节。事务管理是通过AOP(面向切面编程)实现的,Spring通过代理机制对目标方法进行事务增强。

Spring事务管理的关键概念:

  1. 事务管理器(Transaction Manager): 事务管理器负责协调事务的开始、提交、回滚等操作。Spring支持多种事务管理器,如DataSourceTransactionManagerJtaTransactionManager等。

  2. 事务定义(Transaction Definition): 定义了事务的隔离级别、传播行为、超时时间等属性。可以通过编程方式或者声明式的方式来配置事务定义。

  3. 事务切面(Transaction Aspect): 通过AOP,Spring将事务的管理与业务逻辑分离,实现了横切关注点的模块化。

Spring事务传播行为:

事务传播行为定义了在方法调用链中,不同方法之间的事务关系。Spring框架支持以下几种事务传播行为:

  1. REQUIRED(默认): 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

  2. SUPPORTS 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式执行。

  3. MANDATORY 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

  4. REQUIRES_NEW 总是创建一个新的事务,如果当前存在事务,则挂起该事务。

  5. NOT_SUPPORTED 总是以非事务方式执行,如果当前存在事务,则挂起该事务。

  6. NEVER 总是以非事务方式执行,如果当前存在事务,则抛出异常。

  7. NESTED 如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则按REQUIRED执行。

示例:

import org.springframework.transaction.annotation.Transactional;

public class MyService {

    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() {
        // ...
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void methodB() {
        // ...
    }
}

在这个例子中,methodA使用默认的事务传播行为REQUIRED,而methodB使用了REQUIRES_NEW。这样,调用methodB时,它会创建一个新的事务,不受methodA的事务影响。

通过配置事务传播行为,开发者能够灵活地控制事务的行为,确保在复杂的业务场景中,事务的一致性和隔离性得到正确的维护。

文章来源:https://blog.csdn.net/XinTeng2012/article/details/135027211
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。