Skip to content

Spring源码分析

一、Spring 5.x核心模块概述

Spring 5.x的核心模块可分为:

  1. IOC容器:负责Bean的定义、创建、依赖注入与生命周期管理(spring-beans模块)。
  2. AOP:基于动态代理实现切面逻辑,解决横切关注点(如日志、事务)(spring-aop模块)。
  3. 上下文(ApplicationContext):扩展IOC容器,提供国际化、事件发布、资源加载等企业级功能(spring-context模块)。
  4. Web模块:如Spring MVC(spring-webmvc)、反应式WebFlux(spring-webflux,Spring 5新增)。
  5. 事务管理:基于AOP实现声明式事务(spring-tx模块)。

本文重点讲解IOCAOPApplicationContext这三个基础模块,它们是Spring的「灵魂」。

二、IOC容器:Bean的生命周期与依赖注入

IOC(Inversion of Control)是Spring的核心思想,即将对象的创建、依赖管理交给容器控制,而非手动new对象。Spring的IOC容器通过BeanFactory接口定义了基本功能,其主要实现类是DefaultListableBeanFactory(以下简称DLBF)。

1. BeanFactory体系结构

BeanFactory是IOC容器的顶层接口,定义了获取Bean、判断Bean存在等方法(如getBean(String name)containsBean(String name))。其核心实现类关系如下:

  • AbstractBeanFactory:实现了BeanFactory的基本功能(如缓存、依赖查找),是抽象基类。
  • AbstractAutowireCapableBeanFactory(以下简称AACBF):扩展了自动装配能力,负责Bean的实例化、属性填充、初始化(如createBean方法)。
  • DefaultListableBeanFactoryBeanFactory的最终实现,整合了BeanDefinition注册、依赖注入、Bean缓存等功能,是Spring容器的「核心大脑」。

DLBF的核心属性:

java
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {
    // 存储BeanDefinition(Bean的定义信息),key是beanName
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
    // 存储beanName的有序列表(保证Bean的加载顺序)
    private final List<String> beanDefinitionNames = new ArrayList<>();
    // 存储单例Bean(一级缓存),key是beanName,value是初始化完成的Bean
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    // 存储提前暴露的未初始化Bean(二级缓存),解决循环依赖
    private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
    // 存储Bean的工厂方法(三级缓存),用于生成提前暴露的Bean
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
}

2. BeanDefinition:Bean的「元数据」

BeanDefinition是Bean的「定义描述」,包含了Bean的类名、** scope**(单例/原型)、依赖关系初始化方法销毁方法等信息。Spring通过BeanDefinitionReader将配置文件(XML/注解)解析为BeanDefinition,并注册到DLBFbeanDefinitionMap中。

示例:解析@Component注解的类为BeanDefinition

java
// 注解Bean定义读取器:解析@Component、@Service等注解
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(beanFactory);
// 扫描指定包,将带有@Component注解的类转换为BeanDefinition
reader.scan("com.example");

BeanDefinition的核心属性:

java
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    // 作用域(singleton/prototype)
    void setScope(String scope);
    // 是否延迟加载(仅单例有效)
    void setLazyInit(boolean lazyInit);
    // 依赖的Bean名称
    void setDependsOn(String... dependsOn);
    // 是否作为自动装配的候选者
    void setAutowireCandidate(boolean autowireCandidate);
    // 初始化方法名(如@PostConstruct)
    void setInitMethodName(String initMethodName);
    // 销毁方法名(如@PreDestroy)
    void setDestroyMethodName(String destroyMethodName);
}

3. Bean的生命周期:从定义到销毁

Spring中Bean的生命周期可分为四大阶段实例化(Instantiation)→ 属性填充(Populate)→ 初始化(Initialization)→ 销毁(Destruction)。以下是AACBFcreateBean方法(核心流程)的源码解析:

(1)实例化:创建Bean对象

实例化是通过反射工厂方法创建Bean对象的过程。Spring会优先使用构造器注入(若有@Autowired标注的构造器),否则使用无参构造器。

源码片段(AACBFdoCreateBean方法)

java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 1. 实例化Bean:创建原始对象(未初始化)
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        // 调用构造器创建实例(反射)
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance(); // 原始对象
    Class<?> beanType = instanceWrapper.getWrappedClass();
    // ...
}

(2)属性填充:依赖注入(DI)

属性填充是将Bean的依赖(如@Autowired标注的字段/方法)注入到实例中的过程。Spring会通过类型匹配@Autowired默认按类型)或名称匹配@Qualifier指定名称)查找依赖的Bean,并注入。

源码片段(AACBFpopulateBean方法)

java
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    // 获取Bean的属性值(如XML中的<property>或注解中的@Value)
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    // 处理自动装配(如@Autowired、@Resource)
    if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // 按名称自动装配:根据属性名查找Bean
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // 按类型自动装配:根据属性类型查找Bean(核心逻辑)
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }
    // ... 将pvs中的属性值注入到Bean中(反射设置字段或调用setter方法)
}

依赖注入的核心逻辑DefaultListableBeanFactoryresolveDependency方法,用于查找依赖的Bean。例如,处理@Autowired注解时,AutowiredAnnotationBeanPostProcessor会调用该方法,根据类型从beanDefinitionMap中查找匹配的Bean。

(3)初始化:执行回调方法

初始化是在Bean实例化、属性填充完成后,执行自定义逻辑的过程。Spring支持三种初始化方式:

  • 接口回调:实现InitializingBean接口,重写afterPropertiesSet方法。
  • 注解回调:使用@PostConstruct注解标注方法(由CommonAnnotationBeanPostProcessor处理)。
  • XML配置:在<bean>标签中指定init-method属性。

源码片段(AACBFinitializeBean方法)

java
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
    // 1. 执行BeanPostProcessor的postProcessBeforeInitialization方法(初始化前回调)
    Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
    // 2. 执行初始化方法
    if (wrappedBean != null) {
        try {
            // 优先执行InitializingBean的afterPropertiesSet方法
            if (mbd != null && mbd.hasInitMethod()) {
                invokeInitMethod(beanName, wrappedBean, mbd);
            } else {
                // 执行@PostConstruct或init-method
                invokeCustomInitMethod(beanName, wrappedBean);
            }
        } catch (Throwable ex) {
            throw new BeanCreationException(...);
        }
    }
    // 3. 执行BeanPostProcessor的postProcessAfterInitialization方法(初始化后回调,如AOP代理创建)
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    return wrappedBean;
}

关键扩展点BeanPostProcessor(Bean后置处理器),用于在Bean初始化前后修改Bean对象。例如:

  • AutowiredAnnotationBeanPostProcessor:处理@Autowired注解的依赖注入(初始化前回调)。
  • AnnotationAwareAspectJAutoProxyCreator:创建AOP代理对象(初始化后回调)。

(4)销毁:执行清理逻辑

销毁是在Bean生命周期结束时(如容器关闭)执行的清理逻辑。支持三种销毁方式:

  • 接口回调:实现DisposableBean接口,重写destroy方法。
  • 注解回调:使用@PreDestroy注解标注方法(由CommonAnnotationBeanPostProcessor处理)。
  • XML配置:在<bean>标签中指定destroy-method属性。

源码片段(DLBFdestroySingletons方法)

java
public void destroySingletons() {
    // 遍历所有单例Bean,执行销毁方法
    for (String beanName : this.singletonNames) {
        destroySingleton(beanName);
    }
}

protected void destroySingleton(String beanName) {
    // 从一级缓存中移除Bean
    Object singletonObject = this.singletonObjects.remove(beanName);
    if (singletonObject != null) {
        // 执行销毁方法(DisposableBean、@PreDestroy、destroy-method)
        if (singletonObject instanceof DisposableBean) {
            ((DisposableBean) singletonObject).destroy();
        }
        // 处理自定义销毁方法
        if (this.destroyMethods.containsKey(beanName)) {
            invokeCustomDestroyMethod(beanName, singletonObject);
        }
    }
}

4. 循环依赖解决:三级缓存

循环依赖是指两个或多个Bean互相依赖(如A→B→A)。Spring通过三级缓存解决单例Bean的循环依赖问题(原型Bean无法解决,会抛出BeanCurrentlyInCreationException)。

三级缓存的作用

  • 一级缓存(singletonObjects):存储初始化完成的单例Bean(最终结果)。
  • 二级缓存(earlySingletonObjects):存储提前暴露的未初始化Bean(用于解决循环依赖时的临时缓存)。
  • 三级缓存(singletonFactories):存储Bean的工厂方法(用于生成提前暴露的Bean,支持AOP代理)。

循环依赖解决流程(以A→B→A为例)

  1. 实例化A(未初始化),将A的工厂方法存入三级缓存singletonFactories)。
  2. 填充A的属性时,发现依赖B,于是实例化B
  3. 实例化B(未初始化),将B的工厂方法存入三级缓存
  4. 填充B的属性时,发现依赖A,于是从三级缓存中获取A的工厂方法,生成A提前暴露对象(若有AOP,则生成代理对象),存入二级缓存earlySingletonObjects),并移除三级缓存中的A
  5. A的提前暴露对象注入B,完成B的初始化,存入一级缓存
  6. B注入A,完成A的初始化,存入一级缓存,并移除二级缓存中的A

源码片段(AACBFdoCreateBean方法)

java
protected Object doCreateBean(...) {
    // 实例化Bean后,提前暴露工厂方法(用于循环依赖)
    if (earlySingletonExposure) {
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    // ... 属性填充、初始化
}

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            this.singletonFactories.put(beanName, singletonFactory); // 存入三级缓存
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}

三、AOP:面向切面编程的实现

AOP(Aspect-Oriented Programming)是Spring的另一核心特性,用于解决横切关注点(如日志、事务、权限)的复用问题。Spring AOP基于动态代理实现,支持JDK动态代理(需接口)和CGLIB代理(无需接口)。

1. AOP核心组件

Spring AOP的核心组件包括:

  • JoinPoint(连接点):程序执行过程中的某个点(如方法调用、字段赋值)。
  • Pointcut(切入点):匹配JoinPoint的表达式(如execution(* com.example.service.*.*(..))),用于指定哪些方法需要被增强。
  • Advice(通知):切入到JoinPoint的逻辑(如@Before@After@Around)。
  • Aspect(切面):Pointcut + Advice的组合(如@Aspect注解的类)。
  • Advisor(通知器):单个Advice与Pointcut的组合(Spring内部使用,将Aspect转换为Advisor)。

2. 动态代理选择逻辑

Spring会根据Bean是否实现接口选择代理方式:

  • 实现接口:优先使用JDK动态代理java.lang.reflect.Proxy)。
  • 未实现接口:使用CGLIB代理org.springframework.cglib.proxy.Enhancer)。
  • 强制使用CGLIB:可通过@EnableAspectJAutoProxy(proxyTargetClass = true)配置。

源码片段(DefaultAopProxyFactorycreateAopProxy方法)

java
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 条件:是否优化、是否强制使用CGLIB、是否实现接口
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException(...);
        }
        // 若目标类是接口或代理类,使用JDK动态代理
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        // 否则使用CGLIB代理
        return new ObjenesisCglibAopProxy(config);
    } else {
        // 使用JDK动态代理
        return new JdkDynamicAopProxy(config);
    }
}

3. AOP代理创建流程

Spring AOP的代理创建由**AnnotationAwareAspectJAutoProxyCreator**(以下简称AAAPC)完成,它是一个BeanPostProcessor,在Bean初始化后(postProcessAfterInitialization方法)创建代理对象。

流程概述

  1. 扫描所有@Aspect注解的类,解析其中的@Before@After等注解,生成对应的AdvicePointcut
  2. AdvicePointcut组合成Advisor(如AspectJPointcutAdvisor)。
  3. 对于每个Bean,检查其是否匹配任何AdvisorPointcut
  4. 若匹配,则为该Bean创建代理对象(JDK或CGLIB)。

源码片段(AAAPCpostProcessAfterInitialization方法)

java
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            // 创建代理对象(核心逻辑)
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 检查是否需要代理(是否匹配任何Advisor的Pointcut)
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        // 创建代理对象
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

4. 代理对象的执行逻辑

无论是JDK动态代理还是CGLIB代理,其核心逻辑都是拦截目标方法调用,执行Advice逻辑

(1)JDK动态代理

JDK动态代理的核心是InvocationHandler接口,Spring实现了JdkDynamicAopProxy类,其invoke方法负责拦截目标方法。

源码片段(JdkDynamicAopProxyinvoke方法)

java
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    MethodInvocation invocation;
    Object oldProxy = null;
    boolean setProxyContext = false;
    // 获取目标对象(被代理的Bean)
    TargetSource targetSource = this.advised.targetSource;
    Object target = null;
    try {
        // 1. 执行前置通知(@Before)
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        // 2. 创建方法调用链(Invocation)
        invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
        // 3. 执行调用链(依次执行Advice和目标方法)
        Object retVal = invocation.proceed();
        // 4. 执行后置通知(@After)
        return retVal;
    } finally {
        // 释放目标对象
        if (target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
        }
    }
}

(2)CGLIB代理

CGLIB代理的核心是MethodInterceptor接口,Spring实现了CglibAopProxy类,其intercept方法负责拦截目标方法。

源码片段(CglibAopProxyintercept方法)

java
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    Object oldProxy = null;
    boolean setProxyContext = false;
    Object target = null;
    TargetSource targetSource = this.advised.targetSource;
    try {
        // 1. 执行前置通知(@Before)
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        // 2. 创建方法调用链(Invocation)
        invocation = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy);
        // 3. 执行调用链(依次执行Advice和目标方法)
        Object retVal = invocation.proceed();
        // 4. 执行后置通知(@After)
        return retVal;
    } finally {
        // 释放目标对象
        if (target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
        }
    }
}

5. 调用链执行逻辑

无论是JDK还是CGLIB代理,invocation.proceed()方法都会触发调用链的执行。调用链中的每个元素都是Interceptor(拦截器),其执行顺序如下(以@Around@Before@After为例):

  1. @Aroundproceed()之前的逻辑。
  2. @Before的逻辑。
  3. 目标方法的执行。
  4. @Aroundproceed()之后的逻辑。
  5. @After的逻辑。

源码片段(ReflectiveMethodInvocationproceed方法)

java
public Object proceed() throws Throwable {
    // 若调用链执行完毕,执行目标方法
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return invokeJoinpoint();
    }
    // 获取下一个拦截器
    Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    // 执行拦截器逻辑(如@Before、@Around)
    if (interceptorOrInterceptionAdvice instanceof Interceptor) {
        Interceptor interceptor = (Interceptor) interceptorOrInterceptionAdvice;
        return interceptor.invoke(this);
    } else {
        // 动态匹配(如@Pointcut表达式)
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}

四、上下文(ApplicationContext):企业级功能扩展

ApplicationContextBeanFactory的扩展,提供了国际化事件发布资源加载环境配置等企业级功能。其核心实现类包括:

  • ClassPathXmlApplicationContext:从类路径加载XML配置文件。
  • AnnotationConfigApplicationContext:从注解配置(如@Configuration@Component)加载Bean。
  • FileSystemXmlApplicationContext:从文件系统加载XML配置文件。

1. ApplicationContext的初始化流程

ApplicationContext的初始化核心是**refresh()方法**,该方法定义了容器的启动流程,包含12个关键步骤(以AnnotationConfigApplicationContext为例)。

源码片段(AbstractApplicationContextrefresh方法)

java
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 1. 准备刷新(初始化环境、记录启动时间)
        prepareRefresh();
        // 2. 获取BeanFactory(创建DLBF实例)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 3. 准备BeanFactory(设置类加载器、添加后置处理器)
        prepareBeanFactory(beanFactory);
        try {
            // 4.  postProcessBeanFactory(子类扩展点,如WebApplicationContext添加Servlet相关Bean)
            postProcessBeanFactory(beanFactory);
            // 5. 执行BeanFactoryPostProcessor(修改BeanDefinition,如@Configuration类的解析)
            invokeBeanFactoryPostProcessors(beanFactory);
            // 6. 注册BeanPostProcessor(用于Bean初始化前后处理)
            registerBeanPostProcessors(beanFactory);
            // 7. 初始化国际化资源(MessageSource)
            initMessageSource();
            // 8. 初始化事件发布器(ApplicationEventMulticaster)
            initApplicationEventMulticaster();
            // 9.  onRefresh(子类扩展点,如WebApplicationContext初始化Servlet容器)
            onRefresh();
            // 10. 注册事件监听器(ApplicationListener)
            registerListeners();
            // 11. 初始化单例Bean(非延迟加载的Bean)
            finishBeanFactoryInitialization(beanFactory);
            // 12. 完成刷新(发布ContextRefreshedEvent事件)
            finishRefresh();
        } catch (BeansException ex) {
            // 异常处理:销毁已创建的Bean,关闭容器
            destroyBeans();
            cancelRefresh(ex);
            throw ex;
        }
    }
}

2. 核心扩展点

ApplicationContext的扩展点主要通过**BeanFactoryPostProcessorBeanPostProcessor**实现:

  • BeanFactoryPostProcessor:在BeanDefinition加载后、Bean实例化前修改BeanDefinition(如@Configuration类的解析)。例如:
    • ConfigurationClassPostProcessor:处理@Configuration注解的类,解析@Bean方法,注册BeanDefinition。
    • PropertyPlaceholderConfigurer:替换属性占位符(如${db.url})。
  • BeanPostProcessor:在Bean实例化后、初始化前后修改Bean对象(如依赖注入、AOP代理)。例如:
    • AutowiredAnnotationBeanPostProcessor:处理@Autowired注解的依赖注入。
    • AnnotationAwareAspectJAutoProxyCreator:创建AOP代理对象。

3. 事件机制

Spring的事件机制基于观察者模式,用于实现组件间的解耦。核心组件包括:

  • ApplicationEvent:事件基类(如ContextRefreshedEventContextClosedEvent)。
  • ApplicationListener:事件监听器(如@EventListener注解的方法)。
  • ApplicationEventMulticaster:事件发布器(负责将事件广播给所有监听器)。

示例:自定义事件与监听器:

java
// 1. 自定义事件(继承ApplicationEvent)
public class CustomEvent extends ApplicationEvent {
    public CustomEvent(Object source) {
        super(source);
    }
}

// 2. 自定义监听器(实现ApplicationListener)
@Component
public class CustomListener implements ApplicationListener<CustomEvent> {
    @Override
    public void onApplicationEvent(CustomEvent event) {
        System.out.println("收到自定义事件:" + event.getSource());
    }
}

// 3. 发布事件(通过ApplicationContext)
@Autowired
private ApplicationContext context;

public void publishEvent() {
    context.publishEvent(new CustomEvent("Hello, Spring!"));
}

五、Spring 5.x新特性

Spring 5.x相对于之前的版本,主要新增了以下特性:

  1. Java 8+支持:要求JDK 8或更高版本,支持lambda表达式、Stream API、Optional等。
  2. 反应式编程:新增spring-webflux模块,支持反应式Web开发(基于Reactor框架),实现非阻塞IO。
  3. JUnit 5支持:通过@ExtendWith(SpringExtension.class)替代@RunWith(SpringJUnit4ClassRunner.class)
  4. 注解驱动的改进:新增@Nullable@NonNull注解,用于空值检查;@Configuration类支持@Bean方法的顺序控制(@Order注解)。
  5. 性能优化:优化了BeanFactory的缓存机制,减少反射调用次数;改进了AOP代理的创建效率。

六、设计模式在Spring中的应用

Spring框架大量使用了设计模式,以下是常见的几种:

  1. 工厂模式BeanFactory是工厂模式的实现,负责创建Bean对象。
  2. 单例模式DLBFsingletonObjects缓存单例Bean,确保每个Bean只创建一次。
  3. 代理模式:AOP使用动态代理(JDK/CGLIB),实现对目标对象的增强。
  4. 观察者模式:事件机制(ApplicationEventApplicationListener)使用观察者模式,实现组件间解耦。
  5. 模板方法模式AbstractApplicationContextrefresh方法是模板方法,定义了容器启动的流程,子类通过重写onRefresh等方法扩展功能。
  6. 策略模式DefaultAopProxyFactory使用策略模式,根据不同的条件选择JDK或CGLIB代理。

七、扩展Spring:自定义组件

Spring提供了丰富的扩展点,允许开发者自定义组件,以下是几个常见的扩展方式:

  1. 自定义BeanFactoryPostProcessor:修改BeanDefinition(如添加自定义属性)。

    java
    @Component
    public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
            beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE); // 将userService改为原型Bean
        }
    }
  2. 自定义BeanPostProcessor:修改Bean对象(如添加自定义注解的处理)。

    java
    @Component
    public class CustomBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof UserService) {
                ((UserService) bean).setName("自定义名称"); // 初始化前修改Bean属性
            }
            return bean;
        }
    }
  3. 自定义Annotation:通过@Import注解导入自定义组件。

    java
    // 自定义注解
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Import(CustomConfig.class)
    public @interface EnableCustomConfig {
    }
    
    // 自定义配置类
    public class CustomConfig {
        @Bean
        public UserService userService() {
            return new UserService();
        }
    }
    
    // 使用自定义注解
    @SpringBootApplication
    @EnableCustomConfig
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }

八、总结

Spring 5.x的核心是IOC(控制反转)和AOP(面向切面编程),通过BeanFactory管理Bean的生命周期,通过动态代理实现切面逻辑。ApplicationContext扩展了BeanFactory,提供了企业级功能(如事件、国际化)。

理解Spring的源码,关键是要抓住流程(如Bean的生命周期、AOP代理创建流程)和扩展点(如BeanPostProcessorBeanFactoryPostProcessor)。通过调试源码(如在DLBFgetBean方法、JdkDynamicAopProxyinvoke方法设断点),可以更深入地理解Spring的工作原理。

Spring的设计理念是**「约定优于配置」(如@Component@Autowired注解)和「松耦合」**(如依赖注入、事件机制),这也是其成为Java生态中最流行框架的原因。

参考资料