Spring核心原理详解
# Spring核心原理详解
# 前言
Spring框架作为Java生态中最流行的开源框架之一,以其强大的功能和优雅的设计理念,成为了企业级应用开发的首选。本文将深入探讨Spring的核心原理,帮助开发者更好地理解和使用Spring框架。
# Spring框架概述
Spring是一个轻量级的控制反转(IoC)和面向切面编程(AOP)的框架。它的核心思想是通过依赖注入(DI)实现松耦合,并通过AOP实现横切关注点的模块化。
# Spring的核心模块

- Spring Core: 提供IoC容器,管理Bean的生命周期
- Spring AOP: 提供面向切面编程的实现
- Spring JDBC: 简化JDBC操作
- Spring MVC: Web应用开发框架
- Spring Transaction: 提供事务管理
- Spring Security: 提供安全框架
# IoC容器:控制反转与依赖注入
# IoC的概念
IoC(Inversion of Control,控制反转)是Spring的核心,它将传统上由应用程序代码直接操控的对象的创建和管理权交给了Spring容器。
# 依赖注入的方式
Spring提供了多种依赖注入的方式:
- 构造器注入:通过构造函数注入依赖
@Service
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
@Autowired
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
2
3
4
5
6
7
8
9
- Setter注入:通过setter方法注入依赖
@Service
public class UserServiceImpl implements UserService {
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
2
3
4
5
6
7
8
9
- 字段注入:直接在字段上注入依赖(不推荐)
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
}
2
3
4
5
# Bean的生命周期
Spring Bean的生命周期包含多个阶段,主要有:
- 实例化(Instantiation):创建Bean实例
- 属性赋值(Populate Properties):设置Bean属性
- 初始化(Initialization):执行初始化方法
- 使用(In Use):Bean可以被应用使用
- 销毁(Destruction):执行销毁方法,释放资源

下面是一个详细展示Bean生命周期的示例:
@Component
public class LifecycleBean implements InitializingBean, DisposableBean,
BeanNameAware, BeanFactoryAware, ApplicationContextAware {
private String name;
public LifecycleBean() {
System.out.println("1. 构造函数执行");
}
public void setName(String name) {
this.name = name;
System.out.println("2. 设置属性");
}
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware接口: " + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("4. BeanFactoryAware接口");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("5. ApplicationContextAware接口");
}
@PostConstruct
public void postConstruct() {
System.out.println("6. @PostConstruct注解");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("7. InitializingBean接口");
}
public void initMethod() {
System.out.println("8. 自定义init方法");
}
@PreDestroy
public void preDestroy() {
System.out.println("9. @PreDestroy注解");
}
@Override
public void destroy() throws Exception {
System.out.println("10. DisposableBean接口");
}
public void destroyMethod() {
System.out.println("11. 自定义destroy方法");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# IoC容器的实现原理
Spring的IoC容器主要由BeanFactory和ApplicationContext接口及其实现类组成。
# BeanFactory
BeanFactory是Spring IoC容器的基础接口,提供了配置框架和基本功能。
// BeanFactory的核心方法
public interface BeanFactory {
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
boolean containsBean(String name);
// ...其他方法
}
2
3
4
5
6
7
8
# ApplicationContext
ApplicationContext是BeanFactory的子接口,提供了更多企业级功能,如国际化、事件发布、资源加载等。
// ApplicationContext继承多个接口
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory,
HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
// 额外方法...
}
2
3
4
5
# Bean的创建过程
- 解析配置:读取XML、注解或Java配置
- 创建BeanDefinition:根据配置创建Bean定义
- 注册BeanDefinition:将Bean定义注册到容器
- 实例化Bean:根据Bean定义创建Bean实例
- 填充属性:注入依赖
- 初始化Bean:调用初始化方法
// 简化的Bean创建过程伪代码
public Object createBean(String beanName, BeanDefinition beanDefinition) {
// 1. 实例化
Object bean = instantiateBean(beanDefinition);
// 2. 填充属性
populateBean(bean, beanDefinition);
// 3. 初始化
initializeBean(bean, beanName);
return bean;
}
2
3
4
5
6
7
8
9
10
11
12
13
# AOP:面向切面编程
# AOP的概念
AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,它允许我们将横切关注点(如日志、事务、安全等)从主业务逻辑中分离出来。
# AOP的核心概念
- 切面(Aspect):横切关注点的模块化,如日志、事务
- 连接点(Join Point):程序执行过程中的某个点,如方法执行
- 通知(Advice):切面在特定连接点执行的动作,如前置通知、后置通知
- 切点(Pointcut):匹配连接点的表达式
- 引入(Introduction):为现有类添加新方法或属性
- 织入(Weaving):将切面应用到目标对象并创建新的代理对象的过程
# Spring AOP的实现方式
Spring AOP主要有两种实现方式:
- 基于JDK动态代理:针对实现了接口的类
- 基于CGLIB:针对没有实现接口的类
# 基于注解的AOP示例
// 定义切面
@Aspect
@Component
public class LoggingAspect {
// 定义切点
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}
// 前置通知
@Before("serviceMethods()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
// 后置通知
@After("serviceMethods()")
public void logAfter(JoinPoint joinPoint) {
System.out.println("After method: " + joinPoint.getSignature().getName());
}
// 环绕通知
@Around("serviceMethods()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long end = System.currentTimeMillis();
System.out.println("Method " + joinPoint.getSignature().getName() + " took " + (end - start) + "ms");
return result;
}
// 异常通知
@AfterThrowing(pointcut = "serviceMethods()", throwing = "ex")
public void logException(JoinPoint joinPoint, Exception ex) {
System.out.println("Exception in " + joinPoint.getSignature().getName() + ": " + ex.getMessage());
}
// 返回通知
@AfterReturning(pointcut = "serviceMethods()", returning = "result")
public void logReturn(JoinPoint joinPoint, Object result) {
System.out.println("Method " + joinPoint.getSignature().getName() + " returned: " + result);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# AOP的实现原理
Spring AOP的实现原理是动态代理,主要有以下步骤:
- 创建代理工厂:根据Bean类型选择JDK动态代理或CGLIB
- 获取通知:根据切点表达式匹配目标方法
- 创建代理对象:将通知织入到目标对象
- 执行代理方法:在目标方法前后执行通知
// JDK动态代理示例
public class JdkDynamicProxyExample {
interface UserService {
void addUser(String username);
}
static class UserServiceImpl implements UserService {
@Override
public void addUser(String username) {
System.out.println("Adding user: " + username);
}
}
static class LoggingInvocationHandler implements InvocationHandler {
private final Object target;
public LoggingInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After method: " + method.getName());
return result;
}
}
public static void main(String[] args) {
UserService target = new UserServiceImpl();
UserService proxy = (UserService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new LoggingInvocationHandler(target)
);
proxy.addUser("admin");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Spring事务管理
# 事务的基本概念
事务是一组操作的集合,这些操作要么全部成功,要么全部失败。事务具有ACID特性:
- 原子性(Atomicity):事务是不可分割的工作单元
- 一致性(Consistency):事务执行前后,数据库状态保持一致
- 隔离性(Isolation):事务执行不受其他事务干扰
- 持久性(Durability):事务一旦提交,结果永久保存
# Spring事务管理方式
Spring提供了两种事务管理方式:
- 编程式事务管理:通过TransactionTemplate或PlatformTransactionManager手动管理事务
- 声明式事务管理:通过@Transactional注解或XML配置管理事务
# 声明式事务示例
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Transactional(rollbackFor = Exception.class)
@Override
public void createUser(User user) {
userRepository.save(user);
// 如果发生异常,事务会回滚
if (user.getUsername().equals("admin")) {
throw new RuntimeException("Admin user already exists");
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 事务传播行为
Spring定义了7种事务传播行为,用于控制事务的传播方式:
- REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务
- SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式执行
- MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
- REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则挂起当前事务
- NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务
- NEVER:以非事务方式执行,如果当前存在事务,则抛出异常
- NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务;如果当前没有事务,则创建一个新的事务
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private PaymentService paymentService;
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void createOrder(Order order) {
orderRepository.save(order);
// 调用支付服务,使用REQUIRES_NEW传播行为
paymentService.processPayment(order.getId(), order.getAmount());
}
}
@Service
public class PaymentServiceImpl implements PaymentService {
@Autowired
private PaymentRepository paymentRepository;
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void processPayment(Long orderId, BigDecimal amount) {
Payment payment = new Payment(orderId, amount);
paymentRepository.save(payment);
// 即使这里抛出异常,也不会导致订单事务回滚
if (amount.compareTo(new BigDecimal("10000")) > 0) {
throw new RuntimeException("Payment amount too large");
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 事务隔离级别
Spring支持5种事务隔离级别,用于解决并发事务问题:
- DEFAULT:使用数据库默认的隔离级别
- READ_UNCOMMITTED:读未提交,可能出现脏读、不可重复读和幻读
- READ_COMMITTED:读已提交,可以防止脏读,但可能出现不可重复读和幻读
- REPEATABLE_READ:可重复读,可以防止脏读和不可重复读,但可能出现幻读
- SERIALIZABLE:串行化,可以防止脏读、不可重复读和幻读,但性能最差
@Transactional(isolation = Isolation.READ_COMMITTED)
public void updateUserBalance(Long userId, BigDecimal amount) {
// 事务操作
}
2
3
4
# Spring设计模式
Spring框架中应用了多种设计模式,理解这些设计模式有助于更好地理解Spring的工作原理:
# 1. 工厂模式
Spring使用工厂模式创建Bean实例,如BeanFactory和ApplicationContext。
// 工厂模式示例
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = context.getBean("userService", UserService.class);
2
3
# 2. 单例模式
Spring默认使用单例模式管理Bean,确保每个Bean只有一个实例。
// 单例Bean配置
@Bean
@Scope("singleton") // 默认是singleton,可以省略
public UserService userService() {
return new UserServiceImpl();
}
2
3
4
5
6
# 3. 代理模式
Spring AOP使用代理模式实现方法拦截和增强。
// 代理模式在AOP中的应用
@Aspect
@Component
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
// 方法执行前的逻辑
Object result = joinPoint.proceed(); // 调用目标方法
// 方法执行后的逻辑
return result;
}
}
2
3
4
5
6
7
8
9
10
11
12
# 4. 模板方法模式
Spring的JdbcTemplate、RestTemplate等使用模板方法模式简化重复代码。
// JdbcTemplate示例
@Autowired
private JdbcTemplate jdbcTemplate;
public User getUserById(Long id) {
return jdbcTemplate.queryForObject(
"SELECT * FROM users WHERE id = ?",
new Object[]{id},
(rs, rowNum) -> {
User user = new User();
user.setId(rs.getLong("id"));
user.setUsername(rs.getString("username"));
return user;
}
);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 5. 观察者模式
Spring的事件机制使用观察者模式实现组件间的解耦。
// 自定义事件
public class UserCreatedEvent extends ApplicationEvent {
private final User user;
public UserCreatedEvent(Object source, User user) {
super(source);
this.user = user;
}
public User getUser() {
return user;
}
}
// 发布事件
@Service
public class UserServiceImpl implements UserService {
@Autowired
private ApplicationEventPublisher eventPublisher;
@Override
public void createUser(User user) {
// 业务逻辑
// ...
// 发布事件
eventPublisher.publishEvent(new UserCreatedEvent(this, user));
}
}
// 监听事件
@Component
public class UserEventListener {
@EventListener
public void handleUserCreatedEvent(UserCreatedEvent event) {
User user = event.getUser();
System.out.println("User created: " + user.getUsername());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# Spring性能优化
# 1. Bean作用域优化
根据实际需求选择合适的Bean作用域,避免不必要的单例Bean。
// 原型作用域,每次获取都创建新实例
@Bean
@Scope("prototype")
public ExpensiveObject expensiveObject() {
return new ExpensiveObject();
}
2
3
4
5
6
# 2. 懒加载
对于不常用的Bean,可以使用懒加载减少启动时间。
@Bean
@Lazy
public ExpensiveService expensiveService() {
return new ExpensiveServiceImpl();
}
2
3
4
5
# 3. 异步处理
使用@Async注解处理耗时操作,提高系统响应性。
@Service
public class EmailServiceImpl implements EmailService {
@Async
@Override
public void sendEmail(String to, String subject, String content) {
// 发送邮件的耗时操作
}
}
2
3
4
5
6
7
8
9
# 4. 缓存优化
使用Spring Cache减少重复计算和数据库访问。
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductRepository productRepository;
@Cacheable(value = "products", key = "#id")
@Override
public Product getProductById(Long id) {
// 只有缓存未命中时才会执行
return productRepository.findById(id).orElse(null);
}
@CacheEvict(value = "products", key = "#product.id")
@Override
public void updateProduct(Product product) {
productRepository.save(product);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 实战案例:构建高性能服务
# 需求场景
构建一个高性能的商品服务,支持商品查询、创建、更新和删除功能,并具备缓存、异步处理和事务管理能力。
# 实现步骤
- 定义实体类
@Entity
@Table(name = "products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private BigDecimal price;
private Integer stock;
// getters and setters
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 定义Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
List<Product> findByNameContaining(String keyword);
}
2
3
- 定义Service接口
public interface ProductService {
Product getProductById(Long id);
List<Product> searchProducts(String keyword);
Product createProduct(Product product);
Product updateProduct(Product product);
void deleteProduct(Long id);
void reduceStock(Long id, Integer quantity);
}
2
3
4
5
6
7
8
- 实现Service
@Service
@CacheConfig(cacheNames = "products")
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductRepository productRepository;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Cacheable(key = "#id")
@Override
public Product getProductById(Long id) {
return productRepository.findById(id).orElse(null);
}
@Cacheable(key = "#keyword")
@Override
public List<Product> searchProducts(String keyword) {
return productRepository.findByNameContaining(keyword);
}
@CachePut(key = "#result.id")
@Transactional
@Override
public Product createProduct(Product product) {
Product savedProduct = productRepository.save(product);
eventPublisher.publishEvent(new ProductCreatedEvent(this, savedProduct));
return savedProduct;
}
@CachePut(key = "#product.id")
@Transactional
@Override
public Product updateProduct(Product product) {
return productRepository.save(product);
}
@CacheEvict(key = "#id")
@Transactional
@Override
public void deleteProduct(Long id) {
productRepository.deleteById(id);
}
@CachePut(key = "#id")
@Transactional(isolation = Isolation.REPEATABLE_READ)
@Override
public void reduceStock(Long id, Integer quantity) {
Product product = productRepository.findById(id)
.orElseThrow(() -> new RuntimeException("Product not found"));
if (product.getStock() < quantity) {
throw new RuntimeException("Insufficient stock");
}
product.setStock(product.getStock() - quantity);
productRepository.save(product);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
- 定义Controller
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
Product product = productService.getProductById(id);
return product != null ? ResponseEntity.ok(product) : ResponseEntity.notFound().build();
}
@GetMapping("/search")
public ResponseEntity<List<Product>> searchProducts(@RequestParam String keyword) {
return ResponseEntity.ok(productService.searchProducts(keyword));
}
@PostMapping
public ResponseEntity<Product> createProduct(@RequestBody Product product) {
return ResponseEntity.status(HttpStatus.CREATED).body(productService.createProduct(product));
}
@PutMapping("/{id}")
public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody Product product) {
product.setId(id);
return ResponseEntity.ok(productService.updateProduct(product));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
productService.deleteProduct(id);
return ResponseEntity.noContent().build();
}
@PostMapping("/{id}/reduce-stock")
public ResponseEntity<Void> reduceStock(@PathVariable Long id, @RequestParam Integer quantity) {
productService.reduceStock(id, quantity);
return ResponseEntity.ok().build();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
- 配置缓存
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(
new ConcurrentMapCache("products")
));
return cacheManager;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
- 配置异步处理
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(25);
executor.setThreadNamePrefix("product-async-");
executor.initialize();
return executor;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 实现事件监听
@Component
public class ProductEventListener {
private static final Logger logger = LoggerFactory.getLogger(ProductEventListener.class);
@Async
@EventListener
public void handleProductCreatedEvent(ProductCreatedEvent event) {
Product product = event.getProduct();
logger.info("Product created: {}", product.getName());
// 执行异步操作,如发送通知、更新索引等
}
}
2
3
4
5
6
7
8
9
10
11
12
13
# 总结
本文深入探讨了Spring的核心原理,包括IoC容器、AOP、事务管理、设计模式以及性能优化等方面。通过理解这些核心原理,开发者可以更好地使用Spring框架,构建高性能、可维护的企业级应用。
Spring的成功在于其优秀的设计理念和灵活的架构,它不仅简化了Java开发,还提供了丰富的企业级功能。随着Spring生态的不断发展,Spring Boot、Spring Cloud等项目的出现,Spring框架将继续在Java生态中发挥重要作用。