源码追踪spring工作流程
Published on 2023-04-14 14:11 in 分类: SSM框架 with 乐多多多多多多
分类: SSM框架

源码追踪spring工作流程

参考链接:

https://blog.csdn.net/FeenixOne/article/details/124983682

https://blog.51cto.com/u_15706988/5464269

https://blog.csdn.net/u013568683/article/details/128771849

一.spring测试环境搭建

1.导入spring相关jar包:

spring-beans

spring-context

spring-core

spring-expression

2.新建spring配置文件 bean.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">

    <bean id="user" class="com.test.spring.User"/>

</beans>
复制代码

3.编写测试类

复制代码
public class User {
    private String name;
    public User(String name) {
        this.name = name;
    }
    public User() {}
    public void add() {
        System.out.println("add....");
    }
}
复制代码
public class testAdd {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        User user = ac.getBean("user", User.class);
        System.out.println(user);
        user.add();
    }
}

二.DEBUG容器创建过程

从测试类的 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); 开始debug,进入 ClassPathXmlApplicationContext,可以看到:

复制代码
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
        super(parent);
//设置配置文件路径
this.setConfigLocations(configLocations); if (refresh) {
//核心步骤
this.refresh(); } }
复制代码

 加载配置文件后,进入refresh()方法,该方法是容器初始化的核心步骤,该方法包含13个方法:

复制代码
public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
// 准备刷新,做一些基本的准备工作
this.prepareRefresh();
// 获得一个刷新的bean容器,实质就是获得bean工厂;加载xml等配置文件,用该文件产生的BeanDefinition来创建一个工厂 ConfigurableListableBeanFactory beanFactory
= this.obtainFreshBeanFactory();
// 准本bean工厂
this.prepareBeanFactory(beanFactory); try {
// 后置增强,方便扩展
this.postProcessBeanFactory(beanFactory);
// 实例化并且执行BFPP
this.invokeBeanFactoryPostProcessors(beanFactory);
// 实例化并且注册所有的BPP
this.registerBeanPostProcessors(beanFactory);
// 国际化设置,一般用不到
this.initMessageSource();
// 初始化应用程序的多播器和广播器
this.initApplicationEventMulticaster();
// 空方法,预留给子类做扩展
this.onRefresh();
// 注册监听器
this.registerListeners();
// 实例化所有非懒加载的实例对象
this.finishBeanFactoryInitialization(beanFactory);
// 完成刷新
this.finishRefresh(); } catch (BeansException var9) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9); } this.destroyBeans(); this.cancelRefresh(var9); throw var9; } finally { this.resetCommonCaches(); } } }
复制代码

三.refresh()包含的13个方法分析

概览图:

方法1:prepareRefresh()

准备刷新,做一些基本的准备工作

复制代码
protected void prepareRefresh() {
// 设置开始时间
this.startupDate = System.currentTimeMillis();
// 关闭状态设置为false
this.closed.set(false);
// 活跃状态设置为true
this.active.set(true);
// 打印日志
if (this.logger.isDebugEnabled()) { if (this.logger.isTraceEnabled()) { this.logger.trace("Refreshing " + this); } else { this.logger.debug("Refreshing " + this.getDisplayName()); } }
// 初始化属性资源
this.initPropertySources();
// 获取环境信息,验证属性信息
this.getEnvironment().validateRequiredProperties();
// 存储预刷新的一些应用信息的监听器
if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners); } else { this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // 创建一些监听器事件的集合 this.earlyApplicationEvents = new LinkedHashSet(); }
复制代码

方法2:obtainFreshBeanFactory()

获得一个刷新的bean容器,实质就是获取工厂,创建容器对象DefaultListableBeanFactory;加载xml配置文件的属性到当前的工厂中,最重要的就是BeanDefiniation

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        return this.getBeanFactory();
    }
复制代码
// 只要进到这个方法,我们创建的一定是一个新的工厂
protected
final void refreshBeanFactory() throws BeansException { if (this.hasBeanFactory()) {
// 如果存在先销毁,后关闭
this.destroyBeans(); this.closeBeanFactory(); } try {
// 创建bean工厂,这里是用的就是DefaultListableBeanFactory,此时创建的工厂里面的属性值都是默认值 DefaultListableBeanFactory beanFactory
= this.createBeanFactory();
// 序列化id beanFactory.setSerializationId(
this.getId());
// 设置一些属性值
this.customizeBeanFactory(beanFactory);
// 加载bean的定义属性值,该方法有很多重载
// 完成配置文件或者配置类文件的加载
this.loadBeanDefinitions(beanFactory); synchronized(this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException var5) { throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5); } }
复制代码

方法3:prepareBeanFactory(beanFactory)

初始化bean工厂,为方法2拿到的工厂,设置某些具体的值

复制代码
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 为bean工厂设置类加载器 beanFactory.setBeanClassLoader(
this.getClassLoader());
// 设置SPEL解析器 beanFactory.setBeanExpressionResolver(
new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
// 添加一个BeanPostProcessor beanFactory.addBeanPostProcessor(
new ApplicationContextAwareProcessor(this));
// 忽略对应接口的实现 beanFactory.ignoreDependencyInterface(EnvironmentAware.
class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// 注册一些依赖 beanFactory.registerResolvableDependency(BeanFactory.
class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 添加一个增强器 beanFactory.addBeanPostProcessor(
new ApplicationListenerDetector(this)); if (beanFactory.containsBean("loadTimeWeaver")) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } if (!beanFactory.containsLocalBean("environment")) { beanFactory.registerSingleton("environment", this.getEnvironment()); } if (!beanFactory.containsLocalBean("systemProperties")) { beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean("systemEnvironment")) { beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment()); } }
复制代码

方法4:postProcessorBeanFactory(beanFactory)

后置增强器,扩展实现;空方法,方便扩展

方法5:invokeBeanFactoryPostProcessors(beanFactory)

实例化并且执行BFPP

复制代码
// 单例对象之前一定调用,因为单例bean创建后只有一份
protected
void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
复制代码

方法6:registerBeanPostProcessors(beanFactory)

实例化并且注册所有BPP,实例化bean之前的准备工作

方法7:initMessageSource()

国际化设置

方法8:initApplicationEventMulticaster()

准备工作

方法9:onRefresh()

空方法,预留给子类做扩展

方法10:registerListeners()

注册监听器,也属于准备工作

复制代码
protected void registerListeners() {
        Iterator var1 = this.getApplicationListeners().iterator();

        while(var1.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var1.next();
            this.getApplicationEventMulticaster().addApplicationListener(listener);
        }

        String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
        String[] var7 = listenerBeanNames;
        int var3 = listenerBeanNames.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            String listenerBeanName = var7[var4];
            this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            Iterator var9 = earlyEventsToProcess.iterator();

            while(var9.hasNext()) {
                ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
                this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }

    }
复制代码

方法11:finishBeanFactoryInitialization(beanFactory)

实例化所有单例对象

复制代码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 把类型转换操作,设置到当前的beanFactory中
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) { beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class)); }
// 判断当前的beanFactory有没有内置的值处理器
if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver((strVal) -> { return this.getEnvironment().resolvePlaceholders(strVal); }); } // 织入Aware String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); String[] var3 = weaverAwareNames; int var4 = weaverAwareNames.length; for(int var5 = 0; var5 < var4; ++var5) { String weaverAwareName = var3[var5]; this.getBean(weaverAwareName); } // 设置类加载器 beanFactory.setTempClassLoader((ClassLoader)null);
// 冻结:某些bean不需要进行修改操作了,放入 beanFactory.freezeConfiguration();
// 实例化所有非懒加载的实例对象 beanFactory.preInstantiateSingletons(); }
复制代码

preInstantiateSingletons=>实例化所有非懒加载的实例对象

复制代码
public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Pre-instantiating singletons in " + this);
        }
        // 拿到所有注册bean的名称
        List<String> beanNames = new ArrayList(this.beanDefinitionNames);
// 循环去创建我们需要的单例对象 Iterator var2
= beanNames.iterator(); while(true) { String beanName; Object bean; do { while(true) { RootBeanDefinition bd; do { do { do { if (!var2.hasNext()) { var2 = beanNames.iterator(); while(var2.hasNext()) { beanName = (String)var2.next(); Object singletonInstance = this.getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged(() -> { smartSingleton.afterSingletonsInstantiated(); return null; }, this.getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } return; } beanName = (String)var2.next();
// 拿到bean的定义信息,就是我们在xml配置文件里面指定的一些属性 bd
= this.getMergedLocalBeanDefinition(beanName);
// 是否是抽象的,单例的,懒加载的 }
while(bd.isAbstract()); } while(!bd.isSingleton()); } while(bd.isLazyInit()); // 判断当前类是否实现了factoryBean接口,一般没实现,直接进入下面的getBean if (this.isFactoryBean(beanName)) { bean = this.getBean("&" + beanName); break; } // 通过beanName,拿到bean this.getBean(beanName); } } while(!(bean instanceof FactoryBean)); FactoryBean<?> factory = (FactoryBean)bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { SmartFactoryBean var10000 = (SmartFactoryBean)factory; ((SmartFactoryBean)factory).getClass(); isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext()); } else { isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit(); } if (isEagerInit) { this.getBean(beanName); } } }
复制代码

 重要方法:

getMergedLocalBeanDefinition()

// 返回一个合并好的RootBeanDefinition,整合父类和子类
protected
RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { RootBeanDefinition mbd = (RootBeanDefinition)this.mergedBeanDefinitions.get(beanName); return mbd != null && !mbd.stale ? mbd : this.getMergedBeanDefinition(beanName, this.getBeanDefinition(beanName)); }

getSingleton()

复制代码
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized(this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }

                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }

                this.beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = this.suppressedExceptions == null;
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet();
                }

                try {
// 实际上就是调用了createBean singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException var16) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw var16; } } catch (BeanCreationException var17) { BeanCreationException ex = var17; if (recordSuppressedExceptions) { Iterator var8 = this.suppressedExceptions.iterator(); while(var8.hasNext()) { Exception suppressedException = (Exception)var8.next(); ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } this.afterSingletonCreation(beanName); } if (newSingleton) { this.addSingleton(beanName, singletonObject); } } return singletonObject; } }
复制代码

 

复制代码
@Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            synchronized(this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }

        return singletonObject;
    }
复制代码

getBean()=>doGetBean()

复制代码
   //获取IoC容器中指定名称的Bean
   public Object getBean(String name) throws BeansException {
       //doGetBean才是真正向IoC容器获取被管理Bean的过程
       return doGetBean(name, null, null, false);
   }
   //获取IoC容器中指定名称和类型的Bean
   public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
       //doGetBean才是真正向IoC容器获取被管理Bean的过程
       return doGetBean(name, requiredType, null, false);
   }
   //获取IoC容器中指定名称和参数的Bean
   public Object getBean(String name, Object... args) throws BeansException {
       //doGetBean才是真正向IoC容器获取被管理Bean的过程
       return doGetBean(name, null, args, false);
   }
   //获取IoC容器中指定名称、类型和参数的Bean
   public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
   //doGetBean才是真正向IoC容器获取被管理Bean的过程
       return doGetBean(name, requiredType, args, false);
   }
    //真正实现向IoC容器获取Bean的功能,也是触发依赖注入功能的地方
    @SuppressWarnings("unchecked")
    protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {

        //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
        //如果指定的是别名,将别名转换为规范的Bean名称
        String beanName = transformedBeanName(name);
        Object bean;

        // Eagerly check singleton cache for manually registered singletons.
        //先从缓存中取是否已经有被创建过的单例类型的Bean,对于单例模式的Bean整个IoC容器中只创建一次,不需要重复创建
        Object sharedInstance = getSingleton(beanName);
        //IoC容器创建单例模式Bean实例对象
        if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                //如果指定名称的Bean在容器中已有单例模式的Bean被创建,直接返回已经创建的Bean
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
            //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是创建对象的工厂Bean,两者之间有区别
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {//缓存没有正在创建的单例模式Bean
            //缓存中已经有已经创建的原型模式Bean,但是由于循环引用的问题导致实例化对象失败
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            //对IoC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
            BeanFactory parentBeanFactory = getParentBeanFactory();
            //当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                //解析指定Bean名称的原始名称
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    //委派容器bean工厂根据指定名称,指定的类型和显式的参数查找
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // Delegation to parent with explicit args.
                    //委派父级容器根据指定名称和显式的参数查找
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else if (requiredType != null) {
                    // No args -> delegate to standard getBean method.
                    //委派父级容器根据指定名称和指定的类型的参数查找
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {
                    //委派父级容器根据指定名称查找
                    return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }

            //创建的Bean是否需要进行类型验证,一般不需要
            if (!typeCheckOnly) {
                //向容器标记指定的Bean已经被创建
                markBeanAsCreated(beanName);
            }

            try {
                //根据指定Bean名称获取其父级的Bean定义,主要解决Bean继承时子类合并父类公共属性问题
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.
                //获取当前Bean所有依赖Bean的名称
                String[] dependsOn = mbd.getDependsOn();
                //如果当前Bean有依赖Bean
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        //把被依赖Bean注册给当前依赖的Bean
                        registerDependentBean(dep, beanName);
                        try {
                            //递归调用getBean方法,获取当前Bean的依赖Bean
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // Create bean instance.
                //创建单例模式Bean的实例对象
                if (mbd.isSingleton()) {
                    //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            //显式地从容器单例模式Bean缓存中清除实例对象
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    //获取给定Bean的实例对象
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                //IoC容器创建原型模式Bean实例对象
                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    // 原型模式(Prototype)是每次都会创建一个新的对象
                    Object prototypeInstance = null;
                    try {
                        //回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象
                        beforePrototypeCreation(beanName);
                        //创建指定Bean对象实例
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        //回调afterPrototypeCreation方法,默认的功能告诉IoC容器指定Bean的原型对象不再创建了
                        afterPrototypeCreation(beanName);
                    }
                    //获取给定Bean的实例对象
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

                //要创建的Bean既不是单态模式,也不是原型模式,则根据Bean定义资源中配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中比较常用,如:request、session、application等生命周期
                else {
                    String scopeName = mbd.getScope();
                    if (!StringUtils.hasLength(scopeName)) {
                        throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
                    }
                    Scope scope = this.scopes.get(scopeName);
                    //Bean定义资源中没有配置生命周期范围,则Bean定义不合法
                    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的实例对象
                        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);
                    }
                }
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }

        // Check if required type matches the type of the actual bean instance.
        //对创建的Bean实例对象进行类型检查
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                //转换成指定类型的bean
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }
复制代码

通过上面对向IOC容器获取bean方法的分析,我们可以看到在spring中,如果bean是单例模式的,则容器在创建之前先从缓存中查找,以确保整个容器只存在一个实例对象;如果bean的定义是原型模式,则容器每次都会重新创建一个新的实例对象。除此之外,bean定义还可以扩展为指定其生命周期范围。

createBean

上面的源码只是定义了根据bean定义的模式,采取不同创建bean实例对象的策略,具体的bean的实例对象的创建过程由createBean方法完成,具体流程:

1.如果是单例bean,尝试从未完成创建的包装bean缓存中获取BeanWrapper(bean的包装类),如果获取成功,还会清除对应的缓存;

2.完成bean的实例化的方法,根据指定bean使用的策略创建bean的实例,如工厂方法,构造方法自动注入,简单初始化

3.获取包装器里的刚创建好的bean实例

4.应用合并后的BeanDefinition后置处理器:执行MergedBeanDefinitionPostProcessor后置处理器增强方法PostProcessorMergedBeanDefinition

5.是否允许提前暴露bean对象(半成品对象)

6.如果允许提前暴露,将会调用addSingletonFactory(String beanName, bjectFactory<?> singletonFactory)方法,将生成bean的工厂ObjectFactory添加到三级缓存中

7.属性填充,对bean各个属性值进行注入,可能存在依赖于其他bean的属性,则会递归初始依赖的bean

8.初始化bean,如执行aware接口,执行init-method方法,BPP后置增强等

9.如果允许早期暴露,需要进行循环依赖检查

10.注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理;

11.完成bean的创建并返回。

复制代码
//创建Bean实例对象  
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
 
    if (logger.isTraceEnabled()) {
        logger.trace("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;
 
    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
 
    // 1、第一步:根据bean定义信息和bean名称解析得到bean的Class类型
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }
 
    // Prepare method overrides.
    try {
        // 2、第二步:验证并准备为此 bean 定义的方法覆盖
        // 对overrides属性进行标记和验证,在xml解析阶段,将lookup-method和replace-method两个标签属性,保存在MethodOverrides中
        mbdToUse.prepareMethodOverrides();
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                                               beanName, "Validation of method overrides failed", ex);
    }
 
    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
 
        // 3、第三步:给InstantiationAwareBeanPostProcessor后置处理器一个机会,返回代理对象用来替换目标bean实例
        // 如果返回不为空就直接返回代理bean(AOP功能就是基于这里判断的)
        // InstantiationAwareBeanPostProcessor: 前置增强方法:postProcessBeforeInstantiation  后置增强方法:postProcessAfterInitialization
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            // 如果bean不为空的话,则直接返回,不执行下面的doCreateBean创建bean实例操作
            return bean;
        }
    } catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                                        "BeanPostProcessor before instantiation of bean failed", ex);
    }
 
    try {
        // 4、第四步:真正创建bean的方法
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
 
        // 5、第五步:返回创建好的bean实例
        return beanInstance;
    } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        // A previously detected exception with proper bean creation context already,
        // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
        throw ex;
    } catch (Throwable ex) {
        throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}
//真正创建Bean的方法  
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
 
    // 实例化bean
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        // 1、如果是单例bean,尝试从未完成创建的包装Bean缓存(factoryBeanInstanceCache)中获取BeanWrapper(bean的包装类), 如果获取成功,还将清除这个缓存
        //     private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>():FactoryBean名称 ==> BeanWrapper
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
 
    // 如果缓存中不存在的话,则调用createBeanInstance创建一个BeanWrapper(bean的包装类)
    if (instanceWrapper == null) {
        // 2、完成bean的实例化的方法,根据指定bean使用的策略创建bean的实例,如工厂方法、构造方法自动注入、简单初始化
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
 
    // 3、获取包装器里面刚创建好的bean实例
    Object bean = instanceWrapper.getWrappedInstance();
    // 获取实例化对象的类型
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }
 
    // 允许后处理器修改合并的 bean 定义
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                // 4、应用合并后的BeanDefinition后置处理器:执行MergedBeanDefinitionPostProcessor后置处理器增强方法postProcessMergedBeanDefinition()
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }
 
    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
 
    // 5、是否允许提前暴露bean对象(即半成品对象)
    // earlySingletonExposure的值由三部分确定:单例bean && 允许循环依赖 && 当前bean正在创建中
    // isSingletonCurrentlyInCreation(beanName)的作用:返回指定的单例 bean 当前是否正在创建中
    // allowCircularReferences:是否允许循环依赖,默认为true
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
 
    // 6、如果允许提前暴露,将会调用addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)方法,将生成bean的工厂ObjectFactory添加到三级缓存(singletonFactories)中
    // addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)是Spring解决循环依赖非常关键的代码
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                         "' to allow for resolving potential circular references");
        }
        // 为避免循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂,将生成bean的工厂添加到三级缓存(singletonFactories)中
        // 第二个参数同样是一个ObjectFactory,是一个函数式接口,当执行ObjectFactory的getObject()方法的时候,实际上执行的是getEarlyBeanReference(beanName, mbd, bean)
        // getEarlyBeanReference(beanName, mbd, bean)的作用: 获取早期访问指定 bean 的引用
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
 
    // 初始化bean实例
    Object exposedObject = bean;
    try {
        // 7、属性填充,对bean各个属性值进行注入,可能存在依赖于其它bean的属性,则会递归初始依赖的bean
        populateBean(beanName, mbd, instanceWrapper);
 
        // 8、初始化Bean,如执行aware接口、执行init-method方法、BeanPostProcessor后置增强等等
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        } else {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }
 
    // 9、如果允许早期暴露,需要进行循环依赖检查
    if (earlySingletonExposure) {
        // earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
        Object earlySingletonReference = getSingleton(beanName, false);
 
        if (earlySingletonReference != null) {
            // 能进入这里,说明Spring检测到发生了循环依赖
            // exposedObject == bean:两者相等,说明bean在执行initializeBean()初始化的时候,没有被后置处理器增强,还是原来那个对象
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                // allowRawInjectionDespiteWrapping: 表示是否允许在循环引用的情况下注入原始 bean 实例,即使注入的 bean 最终被增强器增强包装过,默认是false
                // hasDependentBean(beanName):是否存在其他bean依赖了当前bean
 
                // 获取到依赖当前bean的所有bean的beanName
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    // 尝试移除bean实例,因为执行到这里,说明exposedObject != bean,也就是bean已经被后置处理器增强,不是原来的对象了,他们依赖的是原来的对象,属于脏数据,所以需要移除掉
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        // 使用actualDependentBeans记录那些移除失败的dependentBean
                        actualDependentBeans.add(dependentBean);
                    }
                }
                // 如果存在移除失败的,则需要抛出异常,Spring不允许脏依赖的存在(通过allowRawInjectionDespiteWrapping设置)
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                                                               "Bean with name '" + beanName + "' has been injected into other beans [" +
                                                               StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                                               "] in its raw version as part of a circular reference, but has eventually been " +
                                                               "wrapped. This means that said other beans do not use the final version of the " +
                                                               "bean. This is often the result of over-eager type matching - consider using " +
                                                               "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }
 
    // Register bean as disposable.
    try {
        // 10、注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
 
    // 11、完成bean的创建并返回
    return exposedObject;
}
复制代码

 通过对方法源码的分析,我们看到具体的依赖注入实现在以下两个方法中:

1.createBeanInstance():生成bean所包含的java对象实例

2.populataBean():对bean属性的依赖注入进行处理

下面继续分析这两个方法的代码实现。

 createBeanInstance=>bean对象的实例化

在createBeanInstance方法中,根据指定的初始化策略,使用静态工厂,工厂方法或者容器的自动装配特性生成java实例对象,创建对象的源码如下:

复制代码
//创建Bean的实例对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
 
    // 1、解析bean的Class类型
    Class<?> beanClass = resolveBeanClass(mbd, beanName);
 
    // 如果bean的Class类型不为空、bean不是public修饰的、且bean不允许访问非公共构造函数和方法,那么Spring会抛异常
    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                        "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }
 
    // 2、如果存在用于创建 bean 实例的回调,则从给定的Supplier接口获取一个bean实例
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }
 
    // 3、如果存在工厂方法的话,即设置了factory-method,则使用工厂方法进行实例化
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }
 
    // Shortcut when re-creating the same bean...
    // 标识构造函数和工厂方法是否已经被解析过
    boolean resolved = false;
    // 是否需要自动注入
    boolean autowireNecessary = false;
    // 实例化bean的参数为空
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            // resolvedConstructorOrFactoryMethod其实是一个缓存,存放已经解析过的构造函数和工厂方法,防止重复解析
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                // 如果缓存不为空,则修改resolved为true,标记为已解析
                resolved = true;
                // 是否需要自动注入的值取决于mbd的constructorArgumentsResolved属性(将构造函数参数标记为已解析的包可见字段)
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
 
    // 4、如果构造函数和工厂方法已经被解析过,直接使用前面介绍的缓存resolvedConstructorOrFactoryMethod里面解析好的,如果需要自动注入,则执行构造函数自动注入,否则使用默认构造函数进行实例化
    if (resolved) {
        if (autowireNecessary) {
            // 如果需要自动注入,则执行构造函数自动注入
            return autowireConstructor(beanName, mbd, null, null);
        } else {
            // 如果不需要自动注入,则使用默认构造函数进行实例化
            return instantiateBean(beanName, mbd);
        }
    }
 
    // Candidate constructors for autowiring?
    // 5、传入beanClass和beanName,通过SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()方法,确定用于给定 bean 的候选构造函数
    // 因为一个类可以有多个构造方法,每个构造方法都有不同的参数,所以需要根据参数以及类型去判断最终调用哪一个构造方法并进行实例化
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // 满足下面四个条件的其中一个,都会执行构造函数的自动注入:
    //     a.determineConstructorsFromBeanPostProcessors()方法返回的构造方法不为空;
    //     b.bean的注入类型为AUTOWIRE_CONSTRUCTOR;
    //     c.存在bean定义的构造函数参数值;
    //     d.用于构造函数或工厂方法调用的显式参数不为空;
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        // 执行构造函数的自动注入
        return autowireConstructor(beanName, mbd, ctors, args);
    }
 
    // Preferred constructors for default construction?
    // 6、如果存在用于默认构造的首选构造函数,则执行构造函数的自动注入
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        // 构造函数自动注入
        return autowireConstructor(beanName, mbd, ctors, null);
    }
 
    // 7、如果既不存在工厂方法,也不存在带有参数的构造方法,则使用默认的构造方法进行bean的实例化
    return instantiateBean(beanName, mbd);
}
   //使用默认的无参构造方法实例化Bean对象
   protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
       try {
           Object beanInstance;
           final BeanFactory parent = this;
           //获取系统的安全管理接口,JDK标准的安全管理API
           if (System.getSecurityManager() != null) {
               //这里是一个匿名内置类,根据实例化策略创建实例对象
               beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                   public Object run() {
                       return getInstantiationStrategy().instantiate(mbd, beanName, parent);
                   }
               }, getAccessControlContext());
           }
           else {
               //将实例化的对象封装起来
               beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
           }
           BeanWrapper bw = new BeanWrapperImpl(beanInstance);
           initBeanWrapper(bw);
           return bw;
       }
       catch (Throwable ex) {
           throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
       }
   }
复制代码

经过上面的代码分析,我们可以看出,对使用工厂方法和自动装配特性的bean的实例化比较清楚,调用相应的工厂方法或者参数匹配的构造方法即可完成实例化对象的工作,但是对于我们最常使用的默认的无参构造方法就需要使用相应的初始化策略(JDK的反射机制或者CGLIB)来进行初始化了,在方法getInstantiationStrategy().instantiate中就具体实现类使用初始策略实例化对象。

instantiate

在使用默认的无参构造方法创建bean的实例化对象时,方法instantiate调用了SimpleInstantiationStrategy类中的实例化bean的方法,源码如下:

复制代码
    //使用初始化策略实例化Bean对象
    @Override
    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
        // Don't override the class with CGLIB if no overrides.
        //如果Bean定义中没有方法覆盖,则就不需要CGLIB父类的方法
        if (!bd.hasMethodOverrides()) {
            Constructor<?> constructorToUse;
            synchronized (bd.constructorArgumentLock) {
                //获取对象的构造方法或工厂方法
                constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
                //如果没有构造方法且没有工厂方法
                if (constructorToUse == null) {
                    //使用JDK的反射机制,判断要实例化的Bean是否是接口
                    final Class<?> clazz = bd.getBeanClass();
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
                    try {
                        if (System.getSecurityManager() != null) {
                            //这里是一个匿名内置类,使用反射机制获取Bean的构造方法
                            constructorToUse = AccessController.doPrivileged(
                                    (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                        }
                        else {
                            constructorToUse = clazz.getDeclaredConstructor();
                        }
                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                    }
                    catch (Throwable ex) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                    }
                }
            }
            //使用BeanUtils实例化,通过反射机制调用”构造方法.newInstance(arg)”来进行实例化
            return BeanUtils.instantiateClass(constructorToUse);
        }
        else {
            // Must generate CGLIB subclass.
            //使用CGLIB来实例化对象  
            return instantiateWithMethodInjection(bd, beanName, owner);
        }
    }
复制代码

通过上面的代码分析,我们看到了如果bean有方法覆盖了,则使用JDK的反射机制进行实例化,否则,使用CGLIB进行实例化。

instantiateWithMethodInjection方法调用SimpleInstantiationStrategy的子类CglibSubclassingInstantiationStrategy使用CGLIB来进行初始化,其源码如下:

复制代码
        //使用CGLIB进行Bean对象实例化
        public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
            //创建扩展子类
            Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
            Object instance;
            if (ctor == null) {
                //根据扩展子类生成实例对象
                instance = BeanUtils.instantiateClass(subclass);
            }
            else {
                try {
                    Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
                    //根据构造函数生成实例对象
                    instance = enhancedSubclassConstructor.newInstance(args);
                }
                catch (Exception ex) {
                    throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
                            "Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
                }
            }
            // SPR-10785: set callbacks directly on the instance instead of in the
            // enhanced class (via the Enhancer) in order to avoid memory leaks.
            // 通过回调拦截器为了避免内存泄漏
            Factory factory = (Factory) instance;
            factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
                    new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
                    new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
            return instance;
        }
        /**
         * Create an enhanced subclass of the bean class for the provided bean
         * definition, using CGLIB.
         */
        private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
            //CGLIB中的类
            Enhancer enhancer = new Enhancer();
            //将Bean本身作为其基类
            enhancer.setSuperclass(beanDefinition.getBeanClass());
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            if (this.owner instanceof ConfigurableBeanFactory) {
                ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
                enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
            }
            enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
            enhancer.setCallbackTypes(CALLBACK_TYPES);
            return enhancer.createClass();
        }
    }
复制代码

CGLIB是一个常用的字节码生成器的类库,它提供了一系列API实现java字节码的生成和转换功能。我们在学习JDK的动态代理时都知道,JDK的动态代理只能针对接口,如果一个类没有实现任何接口,要对其进行动态代理只能使用CGLIB。

populateBean=>属性填充

initializeBean=>初始化bean

initializeBean()主要完成如执行aware接口、执行init-method方法、BeanPostProcessor后置增强等工作。

简述initializeBean()方法处理过程:

1、执行Aware方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware;
2、执行BeanPostProcessor后置处理器的前置处理方法:postProcessBeforeInitialization(),允许对bean实例进行包装;
3、执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-method;
4、执行BeanPostProcessor后置处理器的后置处理方法:postProcessAfterInitialization(),允许对bean实例进行包装;

复制代码
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // 1、执行Aware方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    } else {
        invokeAwareMethods(beanName, bean);
    }
 
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 2、执行BeanPostProcessor后置处理器的前置处理方法:postProcessBeforeInitialization(),允许对bean实例进行包装
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
 
    try {
        // 3、执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-method
        invokeInitMethods(beanName, wrappedBean, mbd);
    } catch (Throwable ex) {
        throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        // 4、执行BeanPostProcessor后置处理器的后置处理方法:postProcessAfterInitialization(),允许对bean实例进行包装
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
 
    return wrappedBean;
}
复制代码

invokeAwareMethods()=>执行aware方法

如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

复制代码
// 实现Aware接口的bean在被初始化后,可以取得一些相对应的资源,如BeanFactory、ApplicationContext等,下面就是具体的赋值过程
private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        // 1、如果bean实现了BeanNameAware接口,那么在bean内部可以获取到BeanName属性
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
 
        // 2、如果bean实现了BeanClassLoaderAware接口,那么在bean内部可以获取到BeanClassLoader对象
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
 
        // 3、如果bean实现了BeanFactoryAware接口,那么在bean内部可以获取到BeanFactory工厂对象
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}
复制代码

applyBeanPostProcessorsBeforeInitialization()

执行BeanPostProcessor后置处理器的前置处理方法

复制代码
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    throws BeansException {
 
    Object result = existingBean;
    // 1、获取到当前工厂中注册的所有BeanPostProcessor后置处理器
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 2、执行每一个BeanPostProcessor的前置增强方法:postProcessBeforeInitialization()
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            // 3、如果postProcessBeforeInitialization()返回为空,则直接返回,将不会执行后续的BeanPostProcessor后置处理器的增强
            return result;
        }
        // 4、使用增强后的bean current,赋值给result,然后返回
        result = current;
    }
    return result;
}
复制代码

invokeInitMethods()

执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-method

复制代码
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
    throws Throwable {
    // 1、检查bean是否实现了InitializingBean接口,如果实现了,则需要执行InitializingBean接口的afterPropertiesSet()方法
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isTraceEnabled()) {
            logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
 
        // 2、调用InitializingBean接口的afterPropertiesSet()方法
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                    ((InitializingBean) bean).afterPropertiesSet();
                    return null;
                }, getAccessControlContext());
            } catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        } else {
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }
 
    // 3、调用用户自定义的初始化方法,比如init-method等
    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 执行用户自定义的初始化方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}
    //调用自定义的实例初始化方法
    protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
            throws Throwable {
        //获取自定义的方法名
        String initMethodName = mbd.getInitMethodName();
        Assert.state(initMethodName != null, "No init method set");
        //根据方法名获得方法
        Method initMethod = (mbd.isNonPublicAccessAllowed() ?
                BeanUtils.findMethod(bean.getClass(), initMethodName) :
                ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

        if (initMethod == null) {
            if (mbd.isEnforceInitMethod()) {
                throw new BeanDefinitionValidationException("Could not find an init method named '" +
                        initMethodName + "' on bean with name '" + beanName + "'");
            }
            else {
                if (logger.isTraceEnabled()) {
                    logger.trace("No default init method named '" + initMethodName +
                            "' found on bean with name '" + beanName + "'");
                }
                // Ignore non-existent default lifecycle methods.
                return;
            }
        }

        if (logger.isTraceEnabled()) {
            logger.trace("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
        }
        //如果自定义方法支持接口调用,就提供接口方法
        Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);

        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                ReflectionUtils.makeAccessible(methodToInvoke);
                return null;
            });
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
                        () -> methodToInvoke.invoke(bean), getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {
                InvocationTargetException ex = (InvocationTargetException) pae.getException();
                throw ex.getTargetException();
            }
        }
        else {
            try {
                //运用Java反射执行自定义的方法
                ReflectionUtils.makeAccessible(methodToInvoke);
                methodToInvoke.invoke(bean);
            }
            catch (InvocationTargetException ex) {
                throw ex.getTargetException();
            }
        }
    }
复制代码

applyBeanPostProcessorsAfterInitialization()

执行BeanPostProcessor后置处理器的后置处理方法,实质执行BeanPostProcessor的后置增强方法postProcessAfterInitialization(),完成对bean实例进行包装

复制代码
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {
 
    Object result = existingBean;
    // 1、获取到工厂中注册的所有BeanPostProcessor后置增强器
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 2、执行BeanPostProcessor的后置增强方法postProcessAfterInitialization()
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            // 3、如果postProcessAfterInitialization()返回为空,则直接返回,将不会执行后续的BeanPostProcessor后置处理器的增强
            return result;
        }
        // 4、使用增强后的bean current,赋值给result,然后返回
        result = current;
    }
    return result;
}
复制代码

registerDisposableBeanIfNecessary

注册DisposableBean,用于销毁处理。通过registerDisposableBeanIfNecessary()方法注册DisposableBean,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理。

复制代码
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    // 如果bean的作用域不是prototype,且bean需要在关闭时进行销毁
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        // 如果bean的作用域是singleton,则会注册用于销毁的bean到disposableBeans缓存,执行给定bean的所有销毁工作
        if (mbd.isSingleton()) {
            // Register a DisposableBean implementation that performs all destruction
            // work for the given bean: DestructionAwareBeanPostProcessors,
            // DisposableBean interface, custom destroy method.
            registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        } else {
            // 如果bean的作用域不是prototype、也不是singleton,而是其他作自定义用域的话,则注册一个回调,以在销毁作用域内的指定对象时执行
 
            // A bean with a custom scope...
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
            scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
    }
}
 
public void registerDisposableBean(String beanName, DisposableBean bean) {
    // 注册用于销毁的bean到disposableBeans缓存
    synchronized (this.disposableBeans) {
        // private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
        this.disposableBeans.put(beanName, bean);
    }
}
复制代码

 

问题:为什么循环依赖要使用三级缓存?

 createbeanInstance=>核心的创建和实例化bean的过程,由doCreateBean调用

 大量的反射出现在该方法中,用来创建对象

复制代码
/**
   * Create a new instance for the specified bean, using an appropriate instantiation strategy:
   * factory method, constructor autowiring, or simple instantiation.
   * @param beanName the name of the bean
   * @param mbd the bean definition for the bean
   * @param args explicit arguments to use for constructor or factory method invocation
   * @return a BeanWrapper for the new instance
   * @see #obtainFromSupplier
   * @see #instantiateUsingFactoryMethod
   * @see #autowireConstructor
   * @see #instantiateBean
   */
  protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
      throw new BeanCreationException(mbd.getResourceDescription(), beanName,
          "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
    }

    if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
        if (mbd.resolvedConstructorOrFactoryMethod != null) {
          resolved = true;
          autowireNecessary = mbd.constructorArgumentsResolved;
        }
      }
    }
    if (resolved) {
      if (autowireNecessary) {
        return autowireConstructor(beanName, mbd, null, null);
      }
      else {
        return instantiateBean(beanName, mbd);
      }
    }

    // Candidate constructors for autowiring?
    // 构造器
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
      return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    /**
     * 默认无参构造
     **/
    return instantiateBean(beanName, mbd);
  }
复制代码

instantiateBean(beanName,mbd)=>默认无参构造

复制代码
/**
   * Instantiate the given bean using its default constructor.
   * @param beanName the name of the bean
   * @param mbd the bean definition for the bean
   * @return a BeanWrapper for the new instance
   */
  protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
      Object beanInstance;
      final BeanFactory parent = this;
      if (System.getSecurityManager() != null) {
        beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
            // 实例化只会分配内存空间,设置默认值
            getInstantiationStrategy().instantiate(mbd, beanName, parent),
            getAccessControlContext());
      }
      else {
        beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
      }
      BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      initBeanWrapper(bw);
      return bw;
    }
    catch (Throwable ex) {
      throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
  }
复制代码

instantiate

复制代码
@Override
  public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // Don't override the class with CGLIB if no overrides.
    if (!bd.hasMethodOverrides()) {
      Constructor<?> constructorToUse;
      synchronized (bd.constructorArgumentLock) {
        constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
        if (constructorToUse == null) {
          final Class<?> clazz = bd.getBeanClass();
          if (clazz.isInterface()) {
            throw new BeanInstantiationException(clazz, "Specified class is an interface");
          }
          try {
            if (System.getSecurityManager() != null) {
              constructorToUse = AccessController.doPrivileged(
                  (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
            }
            else {
              constructorToUse = clazz.getDeclaredConstructor();
            }
            bd.resolvedConstructorOrFactoryMethod = constructorToUse;
          }
          catch (Throwable ex) {
            throw new BeanInstantiationException(clazz, "No default constructor found", ex);
          }
        }
      }
      return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
      // Must generate CGLIB subclass.
      return instantiateWithMethodInjection(bd, beanName, owner);
    }
  }
复制代码

BeanUtils.instantiateClass=>通过构造器反射创建bean

复制代码
/**
   * Convenience method to instantiate a class using the given constructor.
   * <p>Note that this method tries to set the constructor accessible if given a
   * non-accessible (that is, non-public) constructor, and supports Kotlin classes
   * with optional parameters and default values.
   * @param ctor the constructor to instantiate
   * @param args the constructor arguments to apply (use {@code null} for an unspecified
   * parameter, Kotlin optional parameters and Java primitive types are supported)
   * @return the new instance
   * @throws BeanInstantiationException if the bean cannot be instantiated
   * @see Constructor#newInstance
   */
  public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
    Assert.notNull(ctor, "Constructor must not be null");
    try {
      ReflectionUtils.makeAccessible(ctor);
      if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
        return KotlinDelegate.instantiateClass(ctor, args);
      }
      else {
        Class<?>[] parameterTypes = ctor.getParameterTypes();
        Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
        Object[] argsWithDefaultValues = new Object[args.length];
        for (int i = 0 ; i < args.length; i++) {
          if (args[i] == null) {
            Class<?> parameterType = parameterTypes[i];
            argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
          }
          else {
            argsWithDefaultValues[i] = args[i];
          }
        }
        return ctor.newInstance(argsWithDefaultValues);
      }
    }
    catch (InstantiationException ex) {
      throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
    }
    catch (IllegalAccessException ex) {
      throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
    }
    catch (IllegalArgumentException ex) {
      throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
    }
    catch (InvocationTargetException ex) {
      throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
    }
  }
复制代码

方法12:finishRefresh()

完成刷新

protected void finishRefresh() {
        this.clearResourceCaches();
        this.initLifecycleProcessor();
        this.getLifecycleProcessor().onRefresh();
        this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
        LiveBeansView.registerApplicationContext(this);
    }

方法13:resetCommonCaches()

缓存重置

protected void resetCommonCaches() {
        ReflectionUtils.clearCache();
        AnnotationUtils.clearCache();
        ResolvableType.clearCache();
        CachedIntrospectionResults.clearClassLoader(this.getClassLoader());
    }
/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protectedObjectdoCreateBean(finalStringbeanName, finalRootBeanDefinitionmbd, final@NullableObject[] args)
throwsBeanCreationException {

// Instantiate the bean.
BeanWrapperinstanceWrapper=null;
if (mbd.isSingleton()) {
instanceWrapper=this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper==null) {
/**
* 核心的创建实例化Bean的过程
**/
instanceWrapper=createBeanInstance(beanName, mbd, args);
}
finalObjectbean=instanceWrapper.getWrappedInstance();
Class<?>beanType=instanceWrapper.getWrappedClass();
if (beanType!=NullBean.class) {
mbd.resolvedTargetType=beanType;
}

// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwableex) {
thrownewBeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed=true;
}
}

// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
booleanearlySingletonExposure= (mbd.isSingleton() &&this.allowCircularReferences&&
isSingletonCurrentlyInCreation(beanName));

/**
* 解决循环依赖。使用三级缓存
**/
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '"+beanName+
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () ->getEarlyBeanReference(beanName, mbd, bean));
}

// Initialize the bean instance.
ObjectexposedObject=bean;
try {
/**
* 填充属性,上文的实例化只是默认属性值。填充属性是初始化的第一步,第二步是执行init方法
**/
populateBean(beanName, mbd, instanceWrapper);
/**
* 执行init方法
**/
exposedObject=initializeBean(beanName, exposedObject, mbd);
}
catch (Throwableex) {
if (exinstanceofBeanCreationException&&beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
thrownewBeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}

if (earlySingletonExposure) {
ObjectearlySingletonReference=getSingleton(beanName, false);
if (earlySingletonReference!=null) {
if (exposedObject==bean) {
exposedObject=earlySingletonReference;
}
elseif (!this.allowRawInjectionDespiteWrapping&&hasDependentBean(beanName)) {
String[] dependentBeans=getDependentBeans(beanName);
Set<String>actualDependentBeans=newLinkedHashSet<>(dependentBeans.length);
for (StringdependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
thrownewBeanCurrentlyInCreationException(beanName,
"Bean with name '"+beanName+"' has been injected into other beans ["+
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been "+
"wrapped. This means that said other beans do not use the final version of the "+
"bean. This is often the result of over-eager type matching - consider using "+
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}

// Register bean as disposable.
try {
/**
* 需要销毁的时候,销毁的钩子函数
**/
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationExceptionex) {
thrownewBeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}

returnexposedObject;
}
posted @   乐多多多多多多  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
/* 看板娘 */
点击右上角即可分享
微信分享提示