spring加载总览

spring加载总览

    分析可以从 ApplicationContext  application = new ClassPathXmlApplicationContext("spring.xml")入口,这里使用了java配置类, 就改用抛异常的方式,看下spring的初始化过程。

修改 MyBeanPostProcessor.java如下,在bean初始化后抛出异常。

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    Logger logger = LoggerFactory.getLogger(MyBeanPostProcessor.class);
    
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        logger.info(beanName + " : " + bean);
        if(bean instanceof LogService) {
            throw new RuntimeException();
        }
        return bean;
    }
}

再次运行测试类,会抛出以下信息的异常,就从异常信息分析吧。从异常信息中,可以了解spring初始化的过程。

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'logServiceImpl' defined in file [D:\IdeaProjects\justwriteit\spring5\target\classes\com\dsq\service\impl\LogServiceImpl.class]: Initialization of bean failed; nested exception is java.lang.RuntimeException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:584)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)

看下加载的主方法: org.springframework.context.support.AbstractApplicationContext.refresh()

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        // 记录开始时间,设置initPropertySources和检查必要的环境变量(空方法)
        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.
            // 加载bean definition, 调用 beanFactoryPostproessor, 可以在加载beanDefinition             // 后修改beanDefinition
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 注册beanPostProcessor (aop)
            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.
            // 实例化bean
            finishBeanFactoryInitialization(beanFactory);

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

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

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

            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

org.springframework.context.support.AbstractApplicationContext. invokeBeanFactoryPostProcessors()

/**
     * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
     * respecting explicit order if given.
     * 

Must be called before singleton instantiation. */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }

例如:FactoryPostProcessor.java beanFactory 中有所有bean的定义,可以修改bean的定义,添加修改属性等

@Component
public class FactoryPostProcessor implements BeanFactoryPostProcessor {

   private Logger logger = LoggerFactory.getLogger(FactoryPostProcessor.class);

   public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory)
         throws BeansException {
      logger.info("******BeanFactoryPostProcessor");
      String[] beanStr = configurableListableBeanFactory.getBeanDefinitionNames();
      for (String beanName : beanStr) {
         
         logger.info(beanName);
         if(beanName.equals("userServiceImpl")) {
             BeanDefinition beanDefinition = configurableListableBeanFactory
                           .getBeanDefinition(beanName);
                   MutablePropertyValues m = beanDefinition.getPropertyValues();
                    m.addPropertyValue("username", "lisi");
                    logger.info("change username");
         }
      }
   }
}

你可能感兴趣的:(spring加载总览)