Spring BeanFactory

发布时间:2024年01月20日

BeanFactory 是 Spring 框架的核心接口,它提供了高级工厂模式的实现,能够管理和调配应用中的 beans。BeanFactory 以及它的子类(如 ApplicationContext)负责实例化、配置和装配 beans。

以下是对 BeanFactory 接口和它的默认实现 DefaultListableBeanFactory 的一些关键源码解析。请注意,由于 Spring 源码非常复杂且包含大量的接口和类,这里仅提供部分关键片段的解析。

BeanFactory 接口

BeanFactory 接口定义了 Spring 容器的最基本行为,如获取 bean 实例:

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;

    // 其他方法...
}

DefaultListableBeanFactory 类

DefaultListableBeanFactory 是一个典型的 BeanFactory 实现,它包含了 bean 定义的注册以及依赖的处理。

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

    // Bean定义映射,key是bean的名字,value是Bean定义
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

    // 其他属性...

    @Override
    public <T> T getBean(Class<T> requiredType) throws BeansException {
        return doGetBean(requiredType, null, null, false);
    }

    // doGetBean方法是获取Bean的核心方法,下面会做详细解析
    protected <T> T doGetBean(final String name, final Class<T> requiredType,
            final Object[] args, boolean typeCheckOnly) throws BeansException {
        // 省略代码...
    }

    // 其他方法...
}
doGetBean 方法

doGetBean 方法是实际获取 bean 实例的地方,它会进行很多检查和处理。

protected <T> T doGetBean(final String name, final Class<T> requiredType,
        final Object[] args, boolean typeCheckOnly) throws BeansException {

    // 提取对应的 beanName
    String beanName = transformedBeanName(name);
    Object bean;

    // 尝试从缓存中加载单例
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {
        // 如果不是请求单例,则需要创建 bean
        // 这里涉及到原型bean的创建,或者是在某些情况下单例bean的创建(比如使用了lazy-init的单例bean)
        BeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
        checkMergedBeanDefinition(mbd, beanName, args);

        // 依赖处理
        String[] dependsOn = mbd.getDependsOn();
        if (dependsOn != null) {
            for (String dep : dependsOn) {
                getBean(dep);
                registerDependentBean(dep, beanName);
            }
        }

        // 创建 bean 实例
        if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
                try {
                    return createBean(beanName, mbd, args);
                } catch (BeansException ex) {
                    // 销毁单例以避免悬挂资源
                    destroySingleton(beanName);
                    throw ex;
                }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        } else if (mbd.isPrototype()) {
            // 原型设计模式:每次请求都会创建一个新的实例
            Object prototypeInstance = null;
            try {
                beforePrototypeCreation(beanName);
                prototypeInstance = createBean(beanName, mbd, args);
            } finally {
                afterPrototypeCreation(beanName);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
        } else {
            // 其他作用域的处理
            String scopeName = mbd.getScope();
            final Scope scope = this.scopes.get(scopeName);
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
            }
            try {
                Object scopedInstance = scope.get(beanName, () -> {
                    beforePrototypeCreation(beanName);
                    try {
                        return createBean(beanName, mbd, args);
                    } finally {
                        afterPrototypeCreation(beanName);
                    }
                });
                bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            } catch (IllegalStateException ex) {
                throw new BeanCreationException(beanName,
                        "Scope '" + scopeName + "' is not active for the current thread; " +
                        "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                        ex);
            }
        }
    }

    // 检查需要的类型是否符合bean的实际类型
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
        } catch (TypeMismatchException e) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

doGetBean 方法中,Spring 容器首先会从缓存中查找对应的单例 bean,如果找到就使用,否则会根据 BeanDefinition 创建新的 bean 实例。创建过程包括了初始化前的依赖检查、依赖注入、初始化方法的调用以及可能的 AOP 代理相关处理。

此外,对于原型(prototype)作用域的 beans,每次调用 getBean 时都会创建一个新实例,而对于自定义作用域,将根据相应的作用域规则来决定 bean 的创建和生命周期管理。

小结

上面的代码演示是一个非常精简的 BeanFactoryDefaultListableBeanFactory 的源码解析,实际上在 Spring 框架中,这些类包含更多的方法和更复杂的逻辑。

在使用 BeanFactory 时,你需要注意以下几点:

  • 确保 bean 的定义(BeanDefinition)是正确的,包括类的定义、依赖关系、作用域等。
  • 注意 bean 的生命周期,特别是单例和原型作用域的差异。
  • 当使用 AOP 或事务时,了解代理对象(可能是 JDK 动态代理或 CGLIB 代理)的创建过程和它们如何影响实际的 bean 行为。
  • 在多线程环境中,意识到相关的线程安全问题,特别是在使用原型作用域 beans 时。
  • 在进行性能优化时,考虑 bean 的懒加载和预实例化策略。

Spring 框架的源码是学习 Java 设计模式和高级框架架构的宝库,对于有志于深入理解 Spring 的开发人员来说,直接阅读和分析其源码是非常有价值的。

文章来源:https://blog.csdn.net/qq_43012298/article/details/135694499
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。