Spring常见面试题

发布于:2025-08-15 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、BeanFactory与ApplicationContext的区别

特性 BeanFactory ApplicationContext
容器级别 基础容器接口 BeanFactory的子接口,提供更多企业级功能
初始化时机 懒加载(Lazy),使用时才初始化Bean 启动时预加载(饿加载),立即初始化所有单例Bean
自动注册 不支持自动注册BeanPostProcessor等 自动注册BeanPostProcessor、BeanFactoryPostProcessor等
国际化支持 不支持 支持(i18n)
事件发布 不支持 支持应用事件发布机制
资源访问 基本功能 提供更强大的资源访问能力(如URL资源)
AOP支持 需要额外配置 内置支持

使用建议

  • 大多数应用:应使用ApplicationContext,它提供了更完整的Spring功能

  • 特殊场景:只有在资源非常有限(如移动设备)或需要精确控制Bean初始化时才考虑使用BeanFactory

二、请解释Spring Bean的生命周期? 

  1. 实例化(Instantiation):通过构造函数或工厂方法创建Bean实例

  2. 属性填充(Populate Properties):设置Bean的属性和依赖

  3. BeanNameAware回调:调用setBeanName()方法

  4. BeanFactoryAware回调:调用setBeanFactory()方法

  5. ApplicationContextAware回调:调用setApplicationContext()方法

  6. BeanPostProcessor前置处理:调用postProcessBeforeInitialization()

  7. InitializingBean回调:调用afterPropertiesSet()

  8. 自定义初始化方法:调用指定的init-method

  9. BeanPostProcessor后置处理:调用postProcessAfterInitialization()

  10. Bean就绪:Bean可以使用了

  11. DisposableBean回调:容器关闭时调用destroy()

  12. 自定义销毁方法:调用指定的destroy-method

三、Spring 如何保证 Controller 并发的安全?

1. Controller 的默认作用域

  • 单例模式:默认情况下,Spring MVC 的 Controller 是单例的(Singleton)

  • 优点:减少对象创建开销,提高性能

  • 风险:如果 Controller 有实例变量,可能引发线程安全问题

2. 保证并发安全的核心原则

     不使用实例变量

@Controller
public class SafeController {
    // 安全:不使用实例变量
    @GetMapping("/safe")
    public String handleRequest() {
        // 只使用局部变量
        int localVar = 0;
        return "view";
    }
}

        使用线程安全对象

@Controller
public class SafeController {
    // 安全:使用线程安全的实例变量
    private final AtomicInteger counter = new AtomicInteger(0);
    
    @GetMapping("/count")
    public String countRequest() {
        counter.incrementAndGet();
        return "countView";
    }
}

3. Spring 提供的并发安全机制

3.1 方法参数注入

@PostMapping("/process")
public String processForm(@ModelAttribute FormData formData) {
    // formData 是每个请求独立的
}

3.2 使用 ThreadLocal

@Controller
public class UserController {
    private static final ThreadLocal<User> currentUser = new ThreadLocal<>();
    
    @GetMapping("/profile")
    public String showProfile() {
        User user = currentUser.get();
        // 使用user对象
    }
}

3.3 使用请求作用域或会话作用域Bean

@Controller
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedController {
    // 每个请求都有新实例
}

4. 最佳实践总结

  1. 保持无状态:Controller 尽量不维护任何状态

  2. 使用局部变量:所有业务数据通过方法参数或局部变量处理

  3. 线程安全对象:必须使用共享资源时,选择线程安全的实现

  4. 合理使用作用域

    • 单例(默认):适合无状态 Controller

    • 请求作用域:需要为每个请求创建实例时使用

    • 会话作用域:需要维护用户会话状态时使用

  5. 避免

    • 非final的实例变量

    • 非线程安全的集合

    • 静态变量存储请求相关数据

四、请说明使用spring框架的好处

1. 全面的基础设施支持

  • 一站式解决方案:覆盖IoC、AOP、数据访问、Web开发、安全、消息服务等

  • 模块化设计:可按需引入模块(Spring Core、MVC、Data、Security等)

  • 简化配置:支持XML、注解和Java Config多种配置方式

2. 核心优势:控制反转(IoC)和依赖注入(DI)

3. 面向切面编程(AOP)支持

4. 强大的数据访问支持

统一的数据访问异常体系

@Repository
public class UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public User findById(Long id) {
        // 无需处理SQLException
        return jdbcTemplate.queryForObject(...);
    }
}

支持多种持久化技术

  • JDBC

  • JPA/Hibernate

  • MyBatis

  • MongoDB等NoSQL

5. 声明式事务管理

五、java事务类型

1. 编程式事务管理(Programmatic Transaction Management)

@Service
public class OrderService {
    
    @Autowired
    private TransactionTemplate transactionTemplate;
    
    public void processOrder() {
        transactionTemplate.execute(status -> {
            try {
                // 业务逻辑
                return true; // 提交事务
            } catch (Exception e) {
                status.setRollbackOnly(); // 回滚事务
                return false;
            }
        });
    }
}

特点

  • 模板方法模式

  • 减少样板代码

  • 异常时自动回滚

2. 声明式事务管理(Declarative Transaction Management)(推荐)

通过配置或注解定义事务行为,Spring通过AOP在运行时管理事务

2.1 XML配置方式

<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="save*" propagation="REQUIRED"/>
        <tx:method name="get*" read-only="true"/>
    </tx:attributes>
</tx:advice>

<!-- 应用AOP配置 -->
<aop:config>
    <aop:advisor advice-ref="txAdvice" 
                 pointcut="execution(* com.example.service.*.*(..))"/>
</aop:config>

2.2 注解驱动方式(最常用)

@Configuration
@EnableTransactionManagement // 启用注解事务
public class AppConfig {
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}
@Service
public class OrderService {
    
    @Transactional(
        propagation = Propagation.REQUIRED,
        isolation = Isolation.DEFAULT,
        timeout = 30,
        rollbackFor = {BusinessException.class}
    )
    public void placeOrder(Order order) {
        // 业务逻辑
    }
}

3. 事务管理类型对比

特性 编程式事务 声明式事务
控制方式 代码显式控制 配置/注解定义
侵入性
灵活性 中等
代码复杂度
适用场景 需要精细控制事务边界 大多数常规业务场景
维护性 较差 良好

网站公告

今日签到

点亮在社区的每一天
去签到