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");
}
}
}
}