DukeDuke
主页
文档转换
关于我们
主页
文档转换
关于我们
  • 目录

    • Spring简介
    • Springboot简介
    • Spring Security简介
    • SpringBoot 中的事件详解
    • SpringBoot 中的定时任务详解
    • SpringBoot 自动装配原理与源码解释
    • Spring 面试题
    • Spring 核心概念
    • Spring IoC 容器
    • Spring AOP
    • Spring Bean 生命周期
    • Spring 事务管理
    • SpringMVC
    • SpringBoot
    • Spring 性能优化
    • Spring 安全
    • 实际应用场景

Spring 面试题

目录

  • Spring 核心概念
  • Spring IoC 容器
  • Spring AOP
  • Spring Bean 生命周期
  • Spring 事务管理
  • SpringMVC
  • SpringBoot
  • Spring 性能优化
  • Spring 安全
  • 实际应用场景

Spring 核心概念

1. 什么是 Spring 框架?它的核心特性是什么?

答案: Spring 是一个轻量级的、开源的 Java 企业级应用开发框架,由 Rod Johnson 在 2003 年创建。

核心特性:

  • IoC(控制反转):将对象的创建和依赖关系的管理交给 Spring 容器
  • AOP(面向切面编程):将横切关注点从业务逻辑中分离出来
  • 依赖注入(DI):通过配置文件或注解自动注入依赖对象
  • 声明式事务管理:通过注解或 XML 配置管理事务
  • 模块化设计:各个模块可以独立使用

实际应用场景:

// 传统方式
public class UserService {
    private UserDao userDao = new UserDaoImpl(); // 硬编码依赖

    public User getUser(Long id) {
        return userDao.findById(id);
    }
}

// Spring方式
@Service
public class UserService {
    @Autowired
    private UserDao userDao; // Spring自动注入依赖

    public User getUser(Long id) {
        return userDao.findById(id);
    }
}

2. Spring 框架的模块架构是怎样的?

答案: Spring 框架采用分层架构,主要包含以下模块:

核心容器层(Core Container):

  • spring-core:核心工具类
  • spring-beans:Bean 工厂和 Bean 的装配机制
  • spring-context:构建于 core 和 beans 模块之上,提供框架式的对象访问方式
  • spring-expression:Spring 表达式语言

数据访问层(Data Access/Integration):

  • spring-jdbc:JDBC 抽象层
  • spring-orm:对象关系映射集成
  • spring-oxm:对象 XML 映射
  • spring-jms:Java 消息服务

Web 层:

  • spring-web:基本的 Web 开发功能
  • spring-webmvc:MVC 框架
  • spring-websocket:WebSocket 支持

AOP 层:

  • spring-aop:面向切面编程
  • spring-aspects:AspectJ 集成

测试层:

  • spring-test:单元测试和集成测试支持

Spring IoC 容器

3. 什么是 IoC?它的工作原理是什么?

答案: IoC(Inversion of Control,控制反转)是一种设计模式,它将原本在程序中手动创建对象的控制权交给 Spring 框架来管理。

工作原理:

  1. 配置元数据:通过 XML、注解或 Java 代码配置 Bean 的定义
  2. Bean 工厂:Spring 容器读取配置元数据
  3. 依赖解析:解析 Bean 之间的依赖关系
  4. 对象创建:创建 Bean 实例并注入依赖
  5. 生命周期管理:管理 Bean 的创建、使用和销毁

代码示例:

// 配置类
@Configuration
public class AppConfig {

    @Bean
    public UserDao userDao() {
        return new UserDaoImpl();
    }

    @Bean
    public UserService userService() {
        return new UserService(userDao()); // 依赖注入
    }
}

// 使用
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);

4. Spring IoC 容器有哪些?它们有什么区别?

答案: Spring 提供了两种主要的 IoC 容器:

1. BeanFactory(基础容器):

  • 最基本的容器,提供基本的 IoC 功能
  • 延迟加载 Bean,只有在 getBean()时才创建
  • 功能相对简单,适合资源受限的环境

2. ApplicationContext(高级容器):

  • 继承自 BeanFactory,提供更多企业级功能
  • 预加载所有单例 Bean
  • 支持国际化、事件发布、资源访问等

具体实现类:

// BeanFactory实现
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));

// ApplicationContext实现
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
ApplicationContext context2 = new AnnotationConfigApplicationContext(AppConfig.class);
ApplicationContext context3 = new FileSystemXmlApplicationContext("file:beans.xml");

区别对比:

特性BeanFactoryApplicationContext
Bean 实例化延迟加载预加载
国际化支持否是
事件发布否是
资源访问基础增强
性能更快启动更快运行

5. Spring Bean 的作用域有哪些?

答案: Spring Bean 支持以下作用域:

1. singleton(单例,默认):

  • 整个 Spring 容器中只有一个 Bean 实例
  • 所有对该 Bean 的引用都指向同一个实例
  • 适合无状态的 Bean

2. prototype(原型):

  • 每次请求都创建一个新的 Bean 实例
  • 适合有状态的 Bean

3. request(请求):

  • 每个 HTTP 请求创建一个新的 Bean 实例
  • 仅在 Web 应用中有效

4. session(会话):

  • 每个 HTTP 会话创建一个新的 Bean 实例
  • 仅在 Web 应用中有效

5. application(应用):

  • 整个 Web 应用创建一个 Bean 实例
  • 仅在 Web 应用中有效

6. websocket:

  • 每个 WebSocket 会话创建一个 Bean 实例

代码示例:

@Component
@Scope("singleton") // 默认,可省略
public class SingletonBean {
    private int count = 0;

    public void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

@Component
@Scope("prototype")
public class PrototypeBean {
    private int count = 0;

    public void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

// 测试
@Autowired
private SingletonBean singletonBean1;
@Autowired
private SingletonBean singletonBean2;
@Autowired
private PrototypeBean prototypeBean1;
@Autowired
private PrototypeBean prototypeBean2;

// singletonBean1 == singletonBean2 (true)
// prototypeBean1 == prototypeBean2 (false)

Spring AOP

6. 什么是 AOP?Spring AOP 的实现原理是什么?

答案: AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,用于将横切关注点(如日志、事务、安全等)从业务逻辑中分离出来。

Spring AOP 实现原理: Spring AOP 使用代理模式实现,主要有两种代理方式:

1. JDK 动态代理(默认):

  • 基于接口的代理
  • 使用Proxy.newProxyInstance()创建代理对象
  • 目标类必须实现接口

2. CGLIB 代理:

  • 基于继承的代理
  • 通过继承目标类创建子类
  • 可以代理没有实现接口的类

代码示例:

// 切面
@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("Before method: " + methodName);
    }

    @After("execution(* com.example.service.*.*(..))")
    public void logAfter(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("After method: " + methodName);
    }

    @Around("execution(* com.example.service.*.*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();
        System.out.println("Method execution time: " + (end - start) + "ms");
        return result;
    }
}

// 目标类
@Service
public class UserService {

    public User getUser(Long id) {
        // 业务逻辑
        return new User(id, "张三");
    }
}

7. Spring AOP 中的切点表达式有哪些?

答案: Spring AOP 支持多种切点表达式:

1. 方法执行切点:

// 匹配所有public方法
@Pointcut("execution(public * *(..))")

// 匹配com.example包下所有类的所有方法
@Pointcut("execution(* com.example.*.*(..))")

// 匹配UserService类的所有方法
@Pointcut("execution(* com.example.service.UserService.*(..))")

// 匹配以get开头的方法
@Pointcut("execution(* get*(..))")

// 匹配特定参数类型的方法
@Pointcut("execution(* *(Long, String))")

2. 方法签名切点:

// 匹配特定注解的方法
@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")

// 匹配特定注解的类
@Pointcut("@within(org.springframework.stereotype.Service)")

// 匹配特定注解的参数
@Pointcut("@args(org.springframework.validation.annotation.Valid)")

3. 组合切点:

// 组合多个切点
@Pointcut("execution(* com.example.service.*.*(..)) && args(id)")
public void serviceMethodWithId(Long id) {}

// 使用组合切点
@Before("serviceMethodWithId(id)")
public void logServiceMethod(Long id) {
    System.out.println("Service method called with id: " + id);
}

Spring Bean 生命周期

8. Spring Bean 的生命周期是怎样的?

答案: Spring Bean 的生命周期包含以下阶段:

1. 实例化阶段:

  • 容器创建 Bean 实例

2. 属性设置阶段:

  • 设置 Bean 的属性值
  • 注入依赖

3. 初始化阶段:

  • 调用 BeanNameAware 接口方法
  • 调用 BeanFactoryAware 接口方法
  • 调用 ApplicationContextAware 接口方法
  • 调用 BeanPostProcessor 的 postProcessBeforeInitialization 方法
  • 调用 InitializingBean 接口的 afterPropertiesSet 方法
  • 调用自定义的 init-method 方法
  • 调用 BeanPostProcessor 的 postProcessAfterInitialization 方法

4. 使用阶段:

  • Bean 可以被使用

5. 销毁阶段:

  • 调用 DisposableBean 接口的 destroy 方法
  • 调用自定义的 destroy-method 方法

代码示例:

@Component
public class LifecycleBean implements BeanNameAware, BeanFactoryAware,
                                   ApplicationContextAware, InitializingBean, DisposableBean {

    private String beanName;
    private BeanFactory beanFactory;
    private ApplicationContext applicationContext;

    public LifecycleBean() {
        System.out.println("1. 构造方法被调用");
    }

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
        System.out.println("2. BeanNameAware.setBeanName被调用: " + name);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
        System.out.println("3. BeanFactoryAware.setBeanFactory被调用");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        System.out.println("4. ApplicationContextAware.setApplicationContext被调用");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("5. @PostConstruct方法被调用");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("6. InitializingBean.afterPropertiesSet被调用");
    }

    public void initMethod() {
        System.out.println("7. 自定义init-method被调用");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("8. @PreDestroy方法被调用");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("9. DisposableBean.destroy被调用");
    }

    public void destroyMethod() {
        System.out.println("10. 自定义destroy-method被调用");
    }
}

配置:

<bean id="lifecycleBean" class="com.example.LifecycleBean"
      init-method="initMethod" destroy-method="destroyMethod"/>

Spring 事务管理

9. Spring 事务管理的核心概念是什么?

答案: Spring 事务管理的核心概念包括:

1. 事务属性(Transaction Attributes):

  • 传播行为(Propagation):定义事务方法之间的调用关系
  • 隔离级别(Isolation):定义事务的隔离程度
  • 超时时间(Timeout):定义事务的超时时间
  • 只读属性(Read-only):定义事务是否为只读
  • 回滚规则(Rollback Rules):定义哪些异常会回滚事务

2. 事务传播行为:

@Transactional(propagation = Propagation.REQUIRED)        // 默认,支持当前事务,如果没有则创建新事务
@Transactional(propagation = Propagation.REQUIRES_NEW)    // 总是创建新事务
@Transactional(propagation = Propagation.SUPPORTS)        // 支持当前事务,如果没有则以非事务方式执行
@Transactional(propagation = Propagation.NOT_SUPPORTED)   // 以非事务方式执行
@Transactional(propagation = Propagation.MANDATORY)       // 必须在事务中执行
@Transactional(propagation = Propagation.NEVER)           // 不能在事务中执行
@Transactional(propagation = Propagation.NESTED)          // 如果存在事务则嵌套执行

3. 事务隔离级别:

@Transactional(isolation = Isolation.DEFAULT)             // 使用数据库默认隔离级别
@Transactional(isolation = Isolation.READ_UNCOMMITTED)    // 读未提交
@Transactional(isolation = Isolation.READ_COMMITTED)      // 读已提交
@Transactional(isolation = Isolation.REPEATABLE_READ)     // 可重复读
@Transactional(isolation = Isolation.SERIALIZABLE)        // 串行化

代码示例:

@Service
@Transactional
public class UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private OrderDao orderDao;

    // 外层事务
    @Transactional(propagation = Propagation.REQUIRED)
    public void createUserWithOrder(User user, Order order) {
        // 保存用户
        userDao.save(user);

        // 调用内层事务方法
        createOrder(order);

        // 如果这里抛出异常,整个事务回滚
        if (user.getName() == null) {
            throw new RuntimeException("用户名不能为空");
        }
    }

    // 内层事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void createOrder(Order order) {
        // 保存订单
        orderDao.save(order);

        // 如果这里抛出异常,只回滚订单,不影响用户
        if (order.getAmount() <= 0) {
            throw new RuntimeException("订单金额必须大于0");
        }
    }
}

10. Spring 事务的实现原理是什么?

答案: Spring 事务通过 AOP 和代理模式实现,具体原理如下:

1. 事务代理创建:

  • Spring 在启动时扫描带有@Transactional注解的类
  • 为这些类创建代理对象
  • 代理对象拦截方法调用,在方法执行前后添加事务逻辑

2. 事务拦截器链:

// 事务拦截器
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // 获取事务属性
        TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(
            invocation.getMethod(), invocation.getThis().getClass());

        // 获取事务管理器
        PlatformTransactionManager tm = determineTransactionManager(txAttr);

        // 创建事务
        TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, methodIdentification(invocation));

        try {
            // 执行目标方法
            Object retVal = invocation.proceed();

            // 提交事务
            commitTransactionAfterReturning(txInfo);
            return retVal;
        } catch (Throwable ex) {
            // 回滚事务
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        } finally {
            // 清理事务信息
            cleanupTransactionInfo(txInfo);
        }
    }
}

3. 事务管理器:

@Configuration
@EnableTransactionManagement
public class TransactionConfig {

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

SpringMVC

11. SpringMVC 的核心组件和工作流程是什么?

答案: SpringMVC 是一个基于 MVC 模式的 Web 框架,其核心组件包括:

核心组件:

  1. DispatcherServlet:前端控制器,接收所有请求
  2. HandlerMapping:处理器映射器,根据 URL 找到对应的 Handler
  3. HandlerAdapter:处理器适配器,调用 Handler
  4. Handler:处理器,执行业务逻辑
  5. ViewResolver:视图解析器,解析视图名称
  6. View:视图,渲染页面

工作流程:

1. 用户发送请求到DispatcherServlet
2. DispatcherServlet调用HandlerMapping找到Handler
3. DispatcherServlet调用HandlerAdapter执行Handler
4. Handler执行完成后返回ModelAndView
5. DispatcherServlet调用ViewResolver解析视图
6. ViewResolver返回View
7. DispatcherServlet调用View渲染页面
8. 返回响应给用户

代码示例:

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    // GET请求,显示用户列表
    @GetMapping("/list")
    public String listUsers(Model model) {
        List<User> users = userService.getAllUsers();
        model.addAttribute("users", users);
        return "user/list"; // 视图名称
    }

    // POST请求,创建用户
    @PostMapping("/create")
    @ResponseBody
    public ResponseEntity<User> createUser(@RequestBody @Valid User user) {
        User savedUser = userService.createUser(user);
        return ResponseEntity.ok(savedUser);
    }

    // PUT请求,更新用户
    @PutMapping("/{id}")
    @ResponseBody
    public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        User updatedUser = userService.updateUser(user);
        return ResponseEntity.ok(updatedUser);
    }

    // DELETE请求,删除用户
    @DeleteMapping("/{id}")
    @ResponseBody
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.ok().build();
    }
}

12. SpringMVC 中的注解有哪些?如何使用?

答案: SpringMVC 提供了丰富的注解:

1. 类级别注解:

@Controller          // 标识这是一个控制器
@RestController      // @Controller + @ResponseBody,用于REST API
@RequestMapping("/api")  // 类级别的路径映射

2. 方法级别注解:

// 请求映射
@GetMapping("/users")           // GET请求
@PostMapping("/users")          // POST请求
@PutMapping("/users/{id}")      // PUT请求
@DeleteM
最近更新:: 2026/4/17 13:21
Contributors: Duke
Prev
SpringBoot 自动装配原理与源码解释
Next
Spring 核心概念