web环境下Spring的启动过程和源码分析

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

web环境下Spring的启动过程

可以先了解一下《Java Web项目启动加载顺序

web.xml 节点加载顺序context-param -> listener -> filter -> servlet

1.web.xml中配置Spring的监听器ContextLoaderListener

    <listener> 
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

2.web容器(如tomcat)初始化ServletContext的过程中会调用触发一个ServletContextEvent,这个事件会触发监听器ContextLoaderListener的contextInitialized方法,开始Spring上下文的初始化过程

    /**
     * Initialize the root web application context.
     */
    @Override
    public void contextInitialized(ServletContextEvent event) {
       initWebApplicationContext(event.getServletContext());
    }

3.生成一个空的WebApplicationContext对象

20191102100511\_1.png

因为WebApplicationContext是一个接口,那到底是生成哪个实现类的实例呢

a.可以在在web.xml中配置

    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.XmlWebApplicationContext</param-value>
    </context-param>

b.如果要是没在web.xml中配置,则默认生成的就是XmlWebApplicationContext的实例

4.

20191102100511\_2.png

设置当前webApplicationContext的parent上下文,一般为null,除非在web.xml中配置。

configureAndRefreshWebApplicationContext(cwac, servletContext)为当前webApplicationContext设置id,值可以在web.xml中配置,也可以默认生成;还将当前servletContext作为属性值设置进当前webApplicationContext;这个方法最后会refresh上下文。

5.调用AbstractApplicationContext的refresh()方法刷新上下文是一个关键性的地方,会发生很多关键的事情,将进行重点讲解,详解请看下文。

6.webApplicationContext配置并刷新完后,将其作为属性塞进servletContext,再做些其它操作后就完成了Spring的Root WebAplication的初始化,这个时候你就可以享受Spring Ioc和AOP带来的便捷了。

7.如果使用了SpringMVC,需要在web.xml配置一个DispatcherServlet作为请求分发控制。

    <servlet>
        <servlet-name>maijia</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <description>加载/WEB-INF/spring/目录下的所有XML作为Spring MVC的配置文件</description>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/spring/spring-web.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

因为DispatcherServlet实现了ApplicationContextAware接口,因此之前初始化好的上下文Root WebApplication会被注入到DispatcherServlet作为即将创建的MVC自己的上下文webApplication的parent,这个类由web容器运行,和普通的Servlety有相同的生命周期。init的时候读取配置的参数contextConfigLocation,MVC上下文的servletContext也会被设置,和之前webApplication中设置的servletContext是同一个哦!wac.setNamespace(getNamespace())设置命名空间,数据来自Spring的xml配置,用来解析xml内容的。wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()))还会注册一个监听器。最终也会调用AbstractApplicationContext.refresh()方法,和Spring Root WebApplication做的是相同的事情,初始化当前上下文。

值得注意的是,IoC容器和上下文的初始化一般不包含bean依赖注入的实现。一般而言,依赖注入发生在应用第一次想容器getBean索取bean时。但有一个例外值得注意,在使用IoC容器时有一个预实例化的配置,这个预实例化是可以配置的,具体可以在bean定义信息的lazyinit属性来设定;有了这个预实例化的特性,用户可以对容器初始化过程中作一个微小的控制;从而改变这个被设置lazyinit属性的bean的依赖注入的发生,使得这个bean的依赖注入在IoC容器初始化时就预先完成了。

实际开发过程中,一般都不手动给bean设置scope和lazyinit属性,默认scope=singleton,lazyinit=false,所以大多数我们要用到的bean在在IoC容器初始化时就预先完成了。

现在开始重点讲解AbstractApplicationContext的refresh()方法

    @Override
    public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
          // Prepare this context for refreshing.
          prepareRefresh();

          // Tell the subclass to refresh the internal bean factory.
          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

          // Prepare the bean factory for use in this context.
          prepareBeanFactory(beanFactory);

          try {
             // Allows post-processing of the bean factory in context subclasses.
             postProcessBeanFactory(beanFactory);

             // Invoke factory processors registered as beans in the context.
             invokeBeanFactoryPostProcessors(beanFactory);

             // Register bean processors that intercept bean creation.
             registerBeanPostProcessors(beanFactory);

             // Initialize message source for this context.
             initMessageSource();

             // Initialize event multicaster for this context.
             initApplicationEventMulticaster();

             // Initialize other special beans in specific context subclasses.
             onRefresh();

             // Check for listener beans and register them.
             registerListeners();

             // Instantiate all remaining (non-lazy-init) singletons.
             finishBeanFactoryInitialization(beanFactory);

             // Last step: publish corresponding event.
             finishRefresh();
          }

          catch (BeansException ex) {
             // Destroy already created singletons to avoid dangling resources.
             destroyBeans();

             // Reset 'active' flag.
             cancelRefresh(ex);

             // Propagate exception to caller.
             throw ex;
          }
       }
    }

1.prepareRefresh();

  ① 这个方法设置context的启动日期。

  ② 设置context当前的状态,是活动状态还是关闭状态。

  ③ 初始化context environment(上下文环境)中的占位符属性来源。

  ④ 验证所有必需的属性。

2.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

让这个类(AbstractApplicationContext)的子类刷新内部bean工厂。实际上就是重新创建一个bean工厂。

在子类中启动refreshBeanFactory()的方法

        @Override
        protected final void refreshBeanFactory() throws BeansException {
            if (hasBeanFactory()) {
                destroyBeans();
                closeBeanFactory();
            }
            try {
                //创建IoC容器,这里使用的是DefaultListableBeanFactory
                DefaultListableBeanFactory beanFactory = createBeanFactory();
                beanFactory.setSerializationId(getId());
                customizeBeanFactory(beanFactory);
                //启动对BeanDefinition的载入,非常重要的一步,将bean的定义信息加载进beanFactory
                loadBeanDefinitions(beanFactory);
                synchronized (this.beanFactoryMonitor) {
                    this.beanFactory = beanFactory;
                }
            }
            catch (IOException ex) {
                throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
            }
        }

loadBeanDefinitions(beanFactory) 将bean的定义信息以BeanDefinition的结构加载进beanFactory。

3.prepareBeanFactory(beanFactory) ;上一步已经把工厂建好了,但是还不能投入使用,因为工厂里什么都没有,还需要配置一些东西。配置这个工厂的标准环境,比如context的类加载器和后处理器。

4.postProcessBeanFactory(beanFactory); 上面对bean工厂进行了许多配置,现在需要对bean工厂进行一些处理。

  ① 添加一个ServletContextAwareProcessor到bean工厂中。

  ② 在bean工厂自动装配的时候忽略一些接口。如:ServletContextAware、ServletConfigAware

  ③ 注册WEB应用特定的域(scope)到bean工厂中,以便WebApplicationContext可以使用它们。比如”request”, “session”, “globalSession”, “application”,

  ④注册WEB应用特定的Environment bean到bean工厂中,以便WebApplicationContext可以使用它们。如:”contextParameters”, “contextAttributes”

5.invokeBeanFactoryPostProcessors(beanFactory);这一步也是对bean工厂进行一些处理。这一步主要是调用所有的bean工厂处理器(BeanFactoryPostProcessor)对bean工厂进行一些处理。这个方法必须在所有的singleton初始化之前调用。

6.registerBeanPostProcessors(beanFactory);注册用来拦截bean创建的BeanPostProcessor bean.这个方法需要在所有的application bean初始化之前调用。把这个注册的任务委托给了PostProcessorRegistrationDelegate来完成。

7.initMessageSource();初始化MessageSource接口的一个实现类。这个接口提供了消息处理功能。主要用于国际化/i18n。

8.initApplicationEventMulticaster();为这个context初始化一个事件广播器(ApplicationEventMulticaster

9.onRefresh();在AbstractApplicationContext的子类中初始化其他特殊的bean。其实就是初始化ThemeSource接口的实例。这个方法需要在所有单例bean初始化之前调用。

10.registerListeners(); 注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的。这不会影响到其它监听器bean。在注册完以后,还会将其前期的事件发布给相匹配的监听器。

  1. finishBeanFactoryInitialization(beanFactory);完成bean工厂的初始化工作。这一步非常复杂,也非常重要,涉及到了bean的创建。第2步中只是完成了BeanDefinition的定义、解析、处理、注册。但是还没有初始化bean实例。这一步将初始化所有非懒加载的单例bean(即所有lazyinit=false且socpe=singleton的bean),继续在下文进行详解。

12.finishRefresh();完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)。

详解finishBeanFactoryInitialization(beanFactory)

        /**
         * Finish the initialization of this context's bean factory,
         * initializing all remaining singleton beans.
         */
        protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
            // Initialize conversion service for this context.
            if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                    beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
                beanFactory.setConversionService(
                        beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
            }

            // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
            String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
            for (String weaverAwareName : weaverAwareNames) {
                getBean(weaverAwareName);
            }

            // Stop using the temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(null);

            // Allow for caching all bean definition metadata, not expecting further changes.
            beanFactory.freezeConfiguration();

            // Instantiate all remaining (non-lazy-init) singletons.
            beanFactory.preInstantiateSingletons();
        }

这个方法我们只需要关注最后一行即可,也就是beanFactory.preInstantiateSingletons();

    DefaultListableBeanFactory
    public void preInstantiateSingletons() throws BeansException {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Pre-instantiating singletons in " + this);
            }

            //获取解析过的所有beanNames
            List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

            // Trigger initialization of all non-lazy singleton beans...
            for (String beanName : beanNames) {
                //获取对应的RootBeanDefinition,其内部就含有BeanDefinition
                RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                //非抽象、单例模式、非lazy-init,满足以上条件的进入到实例化
                if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                    //对FactoryBean的类型实例化
                    if (isFactoryBean(beanName)) {
                        final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                                @Override
                                public Boolean run() {
                                    return ((SmartFactoryBean<?>) factory).isEagerInit();
                                }
                            }, getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                    else {
                        //getBean方法主要进行了对相应的beanName的实例化
                        getBean(beanName);
                    }
                }
            }
            // Trigger post-initialization callback for all applicable beans...
            for (String beanName : beanNames) {
                //获取上述的对应的实例化对象,对SmartInitializingSingleton的实现类进行afterSingletonInstantiated()方法调用
                Object singletonInstance = getSingleton(beanName);
                if (singletonInstance instanceof SmartInitializingSingleton) {
                    final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                    if (System.getSecurityManager() != null) {
                        AccessController.doPrivileged(new PrivilegedAction<Object>() {
                            @Override
                            public Object run() {
                                smartSingleton.afterSingletonsInstantiated();
                                return null;
                            }
                        }, getAccessControlContext());
                    }
                    else {
                                            //会调用InitializingBean的afterPropertiesSet()方法
                        smartSingleton.afterSingletonsInstantiated();
                    }
                }
            }

由此观之,此过程主要实现所有残留的beanNames能被实例化,这里的实例化指的是对beanFactory中beanName对应的RootBeanDefinition中的beanClass进行准确的实例化,包括属性以及方法复用等等,主要是通过DefaultListableBeanFactory#getBean方法。

getBean方法详解

1-1.Spring在初始化bean的时候会调用beanFactory的getBean方法

1-2.getBean调用doGetBean方法,先从bean单例缓存中取,如果取得到则直接返回(如果bean是FactoryBean,则调用其getObject方法返回)

  1. 如果不存在则先从beanFactory中找到bean的BeanDefinition,如果当前的beanFactory找不到对应的beanDefinition,则到父beanFactory找,如果父beanFactory也找不到,则顺着父链往上找。

3.取当前bean的所有依赖bean,这样会触发getBean的递归调用,知道取到一个没有任何依赖的bean为止。

    String[] dependsOn = mbd.getDependsOn();
    if (dependsOn != null) {
       for (String dependsOnBean : dependsOn) {
          if (isDependent(beanName, dependsOnBean)) {
             throw new BeanCreationException("Circular depends-on relationship between '" +
                   beanName + "' and '" + dependsOnBean + "'");
          }
          registerDependentBean(dependsOnBean, beanName);
          getBean(dependsOnBean);
       }
    }

4.获取或生成bean的实例

    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                try {
                    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.
                    destroySingleton(beanName);
                    throw ex;
                }
            }
        });
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }

    else if (mbd.isPrototype()) {
        // It's a prototype -> create a new instance.
        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 '" + scopeName + "'");
        }
        try {
            Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    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);
        }
    }

4-1. 如果作用域是singleton,则会先从单例缓存中找,找得到就直接返回,找不到就调用createBean方法创建一个实例

4-2.如果作用域是prototype,则直接createBean方法创建一个新的实例。

4-3.如果作用域是request、session、global session,则去beanFactory的scopes里去检索相应的bean,有则取值,无则生成并塞入相应的scope中。

bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);

3种情况,都会判断这个bean是不是FactoryBean,如果不是直接返回原来的,如果是则调用其getObject方法返回一个实例。

    上文在创建新的bean实例时会调用AbstractAutowireCapableBeanFactory的createBean方法
        @Override
        protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
                throws BeanCreationException {

            if (logger.isDebugEnabled()) {
                logger.debug("Creating instance of bean '" + beanName + "'");
            }
            // Make sure bean class is actually resolved at this point.
            //判断需要创建的bean是否可以实例化,这个类是否可以通过类加载器来载入
            resolveBeanClass(mbd, beanName);

            // Prepare method overrides.
            try {
                mbd.prepareMethodOverrides();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
                        beanName, "Validation of method overrides failed", ex);
            }

            try {
                // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
                //如果bean配置了PostProcessor,那么返回的是一个proxy
                Object bean = resolveBeforeInstantiation(beanName, mbd);
                if (bean != null) {
                    return bean;
                }
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "BeanPostProcessor before instantiation of bean failed", ex);
            }
            //创建bean实例
            Object beanInstance = doCreateBean(beanName, mbd, args);
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }

1.createBean 会先调用resolveBeforeInstantiation方法尝试创建代理,这个方法详细介绍请看下文

2.如果3-1没有返回代理,createBean最后调用doCreateBean创建bean实例,这个方法详解请看下文

3-1.doCreateBean方法会先调用AbstractAutowireCapableBeanFactory的createBeanInstance方法生成一个简单的bean对象

3-2.doCreateBean方法再调用populateBean(beanName, mbd, instanceWrapper);给简单bean对象填充property values(字段属性值)

4.populateBean执行到最后会调用applyPropertyValues给bean填充属性

  1. doCreateBean在调用完populateBean方法后,调用 initializeBean方法
    populateBean(beanName, mbd, instanceWrapper);
    if (exposedObject != null) {
       exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    AbstractAutowireCapableBeanFactory.initializeBean
    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        invokeAwareMethods(beanName, bean);
                        return null;
                    }
                }, getAccessControlContext());
            }
            else {
                //如果bean实现了Aware接口,则set需要aware的东西
                invokeAwareMethods(beanName, bean);
            }

            Object wrappedBean = bean;
            if (mbd == null || !mbd.isSynthetic()) {
                //执行bean初始化前置processor
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }

            try {
                //这里就开始执行initMethod 和 afterPropertiesSet方法
                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()) {
                //执行bean初始化后置processor
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }
            return wrappedBean;
        }

如果bean实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,则调用bean相应的set方法设值

        private void invokeAwareMethods(final String beanName, final Object bean) {
            if (bean instanceof Aware) {
                if (bean instanceof BeanNameAware) {
                    ((BeanNameAware) bean).setBeanName(beanName);
                }
                if (bean instanceof BeanClassLoaderAware) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
                }
                if (bean instanceof BeanFactoryAware) {
                    ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
                }
            }
        }

initializeBean中比较重要的一步applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization

最后bean的实例就初始化完成了

resolveBeforeInstantiation方法只是为提前生成代理提供可能而已,需要beanFacotry注册了实现InstantiationAwareBeanPostProcessor接口的processor。

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
       Object bean = null;
       if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
          // Make sure bean class is actually resolved at this point.
          if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
             bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);//执行Class初始化前的操作
             if (bean != null) {
                bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);//执行bean初始化后的操作(如schedule定时、bean作为applicationContext的监听器、若满足aop则生成代理类 等等)
          }
          mbd.beforeInstantiationResolved = (bean != null);
       }
       return bean;
    }

applyBeanPostProcessorsAfterInitialization方法,这里就是即将发生AOP的地方,关键性的入口,如果这个bean需要aop,这个方法执行后会返回一个代理类。

    AbstractAutowireCapableBeanFactory的createBeanInstance方法
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, 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());
            }

            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) {
                //bean定义信息autowire=constructor时
                if (autowireNecessary) {
                    return autowireConstructor(beanName, mbd, null, null);
                }
                else {
                    return instantiateBean(beanName, mbd);
                }
            }

            // Need to determine the constructor...
            Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
            if (ctors != null ||
                    mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                    mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
                return autowireConstructor(beanName, mbd, ctors, args);
            }

            // No special handling: simply use no-arg constructor.
            return instantiateBean(beanName, mbd);
        }

重点关注最后一行instantiateBean(beanName, mbd);

        protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
            try {
                Object beanInstance;
                final BeanFactory parent = this;
                if (System.getSecurityManager() != null) {
                    beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        @Override
                        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);
            }
        }

关注beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

来看看SimpleInstantiationStrategy

    public class SimpleInstantiationStrategy implements InstantiationStrategy {

        // FactoryMethod的ThreadLocal对象,线程所有的变量
        private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<Method>();

        // 返回当前线程所有的FactoryMethod变量值
        public static Method getCurrentlyInvokedFactoryMethod() {
            return currentlyInvokedFactoryMethod.get();
        }

        // 第一种实例化方法,实现部分,部分抽象
        @Override
        public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
            // bd对象定义里,是否包含MethodOverride列表;spring有两个标签参数会产生MethodOverrides ,分别是 lookup-method,replaced-method 
            // 没有MethodOverride对象,可以直接实例化
            if (bd.getMethodOverrides().isEmpty()) {
                // 实例化对象的构造方法
                Constructor<?> constructorToUse;
                // 锁定对象,使获得实例化构造方法线程安全
                synchronized (bd.constructorArgumentLock) {
                    // 查看bd对象里是否含有
                    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(new PrivilegedExceptionAction<Constructor<?>>() {
                                    @Override
                                    public Constructor<?> run() throws Exception {
                                        return clazz.getDeclaredConstructor((Class[]) null);
                                    }
                                });
                            }
                            else {
                                constructorToUse =    clazz.getDeclaredConstructor((Class[]) null);
                            }
                            // 生成成功后,赋值给bd对象,后面使用
                            bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                        }
                        catch (Exception ex) {
                            throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                        }
                    }
                }
                // 反射生成对象
                return BeanUtils.instantiateClass(constructorToUse);
            }
            else {
                // 有MethodOverride对象,使用cglib实现实例化
                return instantiateWithMethodInjection(bd, beanName, owner);
            }
        }

        // 第一种实例化方法的抽象部分
        protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner) {
            throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
        }

        // 第二种实例化方法,实现部分,抽象部分
        @Override
        public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
                final Constructor<?> ctor, Object... args) {
            // 查看bd对象是否有MethodOverride对象
            // 没有MethodOverride,则直接实例化对象
            if (bd.getMethodOverrides().isEmpty()) {
                if (System.getSecurityManager() != null) {
                    // use own privileged to change accessibility (when security is on)
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        @Override
                        public Object run() {
                            ReflectionUtils.makeAccessible(ctor);
                            return null;
                        }
                    });
                }
                // 反射实例化对象
                return BeanUtils.instantiateClass(ctor, args);
            }
            else {
                // 有MethodOverride,使用cglib实现实例化
                return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
            }
        }

        // 第二种实例化方法的抽象部分
        protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner,
                Constructor<?> ctor, Object... args) {
            throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
        }

        // 第三种实例化方法,全部实现
        @Override
        public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
                Object factoryBean, final Method factoryMethod, Object... args) {

            try {
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        @Override
                        public Object run() {
                            ReflectionUtils.makeAccessible(factoryMethod);
                            return null;
                        }
                    });
                }
                else {
                    ReflectionUtils.makeAccessible(factoryMethod);
                }

                // currentlyInvokedFactoryMethod,这块暂时还没看到在哪个地方用到了
                // 先取出原有的 Method
                Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
                try {
                    // 设置当前的Method
                    currentlyInvokedFactoryMethod.set(factoryMethod);
                    // 使用factoryMethod实例化对象
                    return factoryMethod.invoke(factoryBean, args);
                }
                finally {
                    // 实例化完成,恢复现场
                    if (priorInvokedFactoryMethod != null) {
                        currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
                    }
                    else {
                        currentlyInvokedFactoryMethod.remove();
                    }
                }
            }
            catch (IllegalArgumentException ex) {
                throw new BeanInstantiationException(factoryMethod.getReturnType(),
                        "Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
                        "args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
            }
            catch (IllegalAccessException ex) {
                throw new BeanInstantiationException(factoryMethod.getReturnType(),
                        "Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
            }
            catch (InvocationTargetException ex) {
                String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";
                if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
                        ((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
                    msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
                            "declaring the factory method as static for independence from its containing instance. " + msg;
                }
                throw new BeanInstantiationException(factoryMethod.getReturnType(), msg, ex.getTargetException());
            }
        }

    }

大多数情况,bean实例化都是用反射实现的,少数情况会用cglib实现


来源:http://ddrv.cn

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » web环境下Spring的启动过程和源码分析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏