一、BeanFactory与ApplicationContext的区别
特性 | BeanFactory | ApplicationContext |
---|---|---|
容器级别 | 基础容器接口 | BeanFactory的子接口,提供更多企业级功能 |
初始化时机 | 懒加载(Lazy),使用时才初始化Bean | 启动时预加载(饿加载),立即初始化所有单例Bean |
自动注册 | 不支持自动注册BeanPostProcessor等 | 自动注册BeanPostProcessor、BeanFactoryPostProcessor等 |
国际化支持 | 不支持 | 支持(i18n) |
事件发布 | 不支持 | 支持应用事件发布机制 |
资源访问 | 基本功能 | 提供更强大的资源访问能力(如URL资源) |
AOP支持 | 需要额外配置 | 内置支持 |
使用建议
大多数应用:应使用ApplicationContext,它提供了更完整的Spring功能
特殊场景:只有在资源非常有限(如移动设备)或需要精确控制Bean初始化时才考虑使用BeanFactory
二、请解释Spring Bean的生命周期?
实例化(Instantiation):通过构造函数或工厂方法创建Bean实例
属性填充(Populate Properties):设置Bean的属性和依赖
BeanNameAware回调:调用
setBeanName()
方法BeanFactoryAware回调:调用
setBeanFactory()
方法ApplicationContextAware回调:调用
setApplicationContext()
方法BeanPostProcessor前置处理:调用
postProcessBeforeInitialization()
InitializingBean回调:调用
afterPropertiesSet()
自定义初始化方法:调用指定的init-method
BeanPostProcessor后置处理:调用
postProcessAfterInitialization()
Bean就绪:Bean可以使用了
DisposableBean回调:容器关闭时调用
destroy()
自定义销毁方法:调用指定的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. 最佳实践总结
保持无状态:Controller 尽量不维护任何状态
使用局部变量:所有业务数据通过方法参数或局部变量处理
线程安全对象:必须使用共享资源时,选择线程安全的实现
合理使用作用域:
单例(默认):适合无状态 Controller
请求作用域:需要为每个请求创建实例时使用
会话作用域:需要维护用户会话状态时使用
避免:
非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. 事务管理类型对比
特性 | 编程式事务 | 声明式事务 |
---|---|---|
控制方式 | 代码显式控制 | 配置/注解定义 |
侵入性 | 高 | 低 |
灵活性 | 高 | 中等 |
代码复杂度 | 高 | 低 |
适用场景 | 需要精细控制事务边界 | 大多数常规业务场景 |
维护性 | 较差 | 良好 |