本文将带你深入了解Spring框架的核心原理,通过300行代码的迷你版本来展示Spring最核心的特性:IoC(控制反转)、DI(依赖注入)和MVC(模型-视图-控制器)模式的实现。
本文相关源码请关注:用300行代码手写Spring核心原理
mini版Spring实现思路

本文将带你深入了解Spring框架的核心原理,通过300行代码的迷你版本来展示Spring最核心的特性:IoC(控制反转)、DI(依赖注入)和MVC(模型-视图-控制器)模式的实现。
本文相关源码请关注:用300行代码手写Spring核心原理

最近上了一个新项目,考虑到一个问题,在高并发场景下,我们无法控制前端的请求频率和次数,这就可能导致服务器压力过大,响应速度变慢,甚至引发系统崩溃等严重问题。为了解决这些问题,我们需要在后端实现一些机制,如接口限流、防重复提交和接口防抖,而这些是保证接口安全、稳定提供服务,以及防止错误数据 和 脏数据产生的重要手段。
而AOP适合在在不改变业务代码的情况下,灵活地添加各种横切关注点,实现一些通用公共的业务场景,例如日志记录、事务管理、安全检查、性能监控、缓存管理、限流、防重复提交等功能。这样不仅提高了代码的可维护性,还使得业务逻辑更加清晰专注,关于AOP不理解的可以看这篇文章。
Spring的核心思想就是容器,当容器refresh的时候,外部看上去风平浪静,其实内部则是一片惊涛骇浪,汪洋一片。Springboot更是封装了Spring,遵循约定大于配置,加上自动装配的机制。很多时候我们只要引用了一个依赖,几乎是零配置就能完成一个功能的装配。
由spring提供的、在容器或bean生命周期各个阶段、供spring框架回调使用的函数方法,即为扩展点。扩展点体现了Spring框架的灵活性、业务亲和性。使开发人员可以在不修改spring源码的情况下,对容器和bean的行为、属性进行额外的管理。
springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题。在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功能。
在一般业务场景,可能是不需要关心一个bean是如何被注册进spring容器的,只需要把需要注册进容器的bean声明为@Component即可,因为spring会自动扫描到这个Bean完成初始化并加载到spring上下文容器。
但是,如果加载Bean的过程中部分Bean和Bean之间存在依赖关系,也就是说Bean A的加载需要等待Bean B加载完成之后才能进行;或者你正在开发某个中间件需要完成自动装配时,你会声明自己的Configuration类,但是可能你面对的是好几个有互相依赖的Bean,如果不加以控制,这时候可能会报找不到依赖的错误。
事务是数据库中不可分割的操作序列,具有原子性、一致性、隔离性和持久性。要么全部执行成功,要么全部失败回滚,以保证数据的完整性和一致性。
事务的四个特性ACID:
Spring框架系列文章建议阅读顺序:全网最详细的Spring入门教程 -》Spring框架IoC核心详解 -》 Spring AOP基础、快速入门 -》 MVC快速入门;而后再阅读其它文章详细内容
开发中我们经常会用到异步方法调用,具体到代码层面,异步方法调用的实现方式有很多种,比如最原始的通过实现Runnable接口或者继承Thread类创建异步线程,然后启动异步线程;再如,可以直接用java.util.concurrent包提供的线程池相关API实现异步方法调用。
如果说可以用一行代码快速实现异步方法调用,那是不是比上面方法香很多。
Spring提供了Async注解,就可以帮助我们一行代码搞定异步方法调用。Async注解用起来是很爽,但是如果不对其底层实现做深入研究,难免有时候也会心生疑虑,甚至会因使用不当,遇见一些让人摸不着头脑的问题。
AOP,面向切面编程,作为面向对象的一种补充,将公共逻辑(事务管理、日志、缓存、权限控制、限流等)封装成切面,跟业务代码进行分离,可以减少系统的重复代码和降低模块之间的耦合度。切面就是那些与业务无关,但所有业务模块都会调用的公共逻辑。
先看一个例子:如何给如下UserServiceImpl中所有方法添加进入方法的日志,
public class UserServiceImpl implements IUserService {
@Override
public List<User> findUserList() {
System.out.println("execute method: findUserList");
return Collections.singletonList(new User("seven", 18));
}
@Override
public void addUser() {
System.out.println("execute method: addUser");
// do something
}
}
AOP是基于IOC的Bean加载来实现的,所以理解Spring AOP的初始化必须要先理解Spring IOC的初始化。然后就能找到初始化的流程和aop对应的handler,即parseCustomElement方法找到parse aop:aspectj-autoproxy的handler(org.springframework.aop.config.AopNamespaceHandler)
AopNamespaceHandler,其实就是注册BeanDefinition的解析器BeanDefinitionParser,将aop:xxxxxx配置标签交给指定的parser来处理。
代理模式(Proxy pattern): 为另一个对象提供一个替身或占位符以控制对这个对象的访问

动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。