一、spring
1、概念解释
spring:java应用程序类与类之间互相协作是比较费劲的,需要在类中自行创建对象并且管理对象的整个生命周期,会造成代码高度耦合和不可想象的复杂度,而spring就是一个帮助java应用程序管理对象创建、依赖关系和生命周期的第三方组件
DI:依赖注入,创建被调用实例的工作由spring容器完成,然后注入调用者
IOC:控制反转,创建被调用者实例的工作不再由调用者来完成
IOC容器:负责创建对象和管理对象之间依赖关系的容器
BeanFactory:最简单的容器接口,只定义了基本的DI功能
ApplicationContext应用上下文:实现了BeanFactory接口和其他各种功能,提供更多企业级的服务
2、模块说明
spring-core:发现、建立和维护每个 Bean 之间的关系所需要的一些列的工具
spring-bean:Bean 的定义(BeanDefinition)、Bean 的创建(BeanFactory)以及对 Bean 的解析
spring-context:Bean的IOC容器(ApplicationContext)
3、ioc容器详细说明(许令波)
ioc作为一个容器,它里面放得都是bean,bean与bean之间的对应关系,而bean之间的对应关系我们开始都是通过xml配置文件来体现的,所以ioc容器需要面对这些问题:
- 对应与对象之间的关系是通过xml配置文件来描述的(当然也可以是properties等文件)
- 描述的文件存放位置在那里,一般来说我们都是放在classpath目录下的,但是也可以是URL、fileSystem
- 文件的解析
- Bean在容器中的表现形式,也就是它的数据结构
对于Spring而言,它用Resource、BeanDefinition、BeanDefinitionReader、BeanFactory、ApplicationContext五个组件来实现以上问题,而同时这5个接口定义了 spring ioc 容器的基本代码组件结构:
Resource:对资源的抽象,它的每一个实现类都代表了一种资源的访问策略,如ClasspathResource 、 URLResource ,FileSystemResource 等
BeanDefinition:用来描述和抽象一个具体的Bean对象,它是描述Bean对象的基本数据结构。配置文件中的每一个bean对应一个BeanDefinition实例
BeanDefinitionReader:外部资源所表达的语义需要转化为内部数据结构BeanDefinition,BeanDefinitionReader起到解析的作用。对应不同的描述需要有不同的Reader 。如 XmlBeanDefinitionReader 用来读取xml 描述配置的 bean 对象
BeanFactory:是一个纯粹的bean容器,它是IOC必备的数据结构,其中BeanDefinition是它的基本结构,它内部维护着一个BeanDefinition map,并可根据BeanDefinition 的描述进行 bean 的创建和管理
ApplicationContext:这个就是大名鼎鼎的Spring容器,它叫做应用上下文,与我们应用息息相关,它继承BeanFactory,是BeanFactory的扩展升级版。由于ApplicationContext的结构就决定了它与BeanFactory的不同,其主要区别有:
- 继承MessageSource,提供国际化的标准访问策略
- 继承ApplicationEventPublisher,提供强大的事件机制
- 扩展ResourceLoader,可以用来加载多个Resource,可以灵活访问不同的资源
- 对Web应用的支持
4、ioc启动流程
ApplicationContext context = new ClassPathXmlApplicationContext("spring-ioc.xml");
在main方法中通过读取xml配置的方式创建应用上下文
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); //设置配置文件路径 setConfigLocations(configLocations); if (refresh) { //执行最核心的刷新方法 this.refresh(); } }
执行AbstractApplicationContext的refresh()方法
public void refresh() throws BeansException, IllegalStateException { synchronized(this.startupShutdownMonitor) { //准备刷新的上下文环境,例如对系统属性或者环境变量进行准备及验证 prepareRefresh(); //初始化BeanFactory,并进行XML文件读取, //这一步之后,ClassPathXmlApplicationContext实际上就已经包含了BeanFactory所提供的功能,也就是可以进行Bean的提取等基础操作了 ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); //对BeanFactory进行各种功能填充,@Qualifier与@Autowired这两个注解正是在这一步骤中增加的支持。 //设置@Autowired和 @Qualifier注解解析器QualifierAnnotationAutowireCandidateResolver prepareBeanFactory(beanFactory); try { //子类覆盖方法做额外的处理,提供了一个空的函数实现postProcessBeanFactory来方便程序员在业务上做进一步扩展 postProcessBeanFactory(beanFactory); //激活各种BeanFactory处理器(spring boot下会执行关键的配置类加载,完成@Configuration注解的配置类装配) invokeBeanFactoryPostProcessors(beanFactory); //注册拦截Bean创建的Bean处理器,这里只是注册,真正的调用是在getBean时候 registerBeanPostProcessors(beanFactory); //为上下文初始化Message源,即不同语言的消息体进行国际化处理 initMessageSource(); //初始化应用消息广播器(如果用户定义了就用用户的,如果没有默认用户ApplicationEventMulticaster) initApplicationEventMulticaster(); //留给子类来初始化其它的Bean onRefresh(); //在所有注册的bean中查找Listener bean,注册到消息广播器中 registerListeners(); //初始化剩下的单实例(非惰性的) finishBeanFactoryInitialization(beanFactory); //完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人 finishRefresh(); } catch (BeansException ex) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + ex); } destroyBeans(); cancelRefresh(ex); throw ex; } finally { resetCommonCaches(); } } }
1)初始化工作,创建ioc容器并加载Bean的定义
在this.obtainFreshBeanFactory()这个方法中会创建一个DefaultListableBeanFactory容器,这个容器是第一个可以独立使用的ioc容器,所有spring ioc容器的始祖
看一下DefaultListableBeanFactory容器的依赖图
protected final void refreshBeanFactory() throws BeansException { //如果已经有容器,销毁容器中的bean,关闭容器 if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { //创建最基础的ioc容器 DefaultListableBeanFactory beanFactory = createBeanFactory(); //为了序列化指定id beanFactory.setSerializationId(getId()); //简单定制化 customizeBeanFactory(beanFactory); //关键方法,加载bean到容器 loadBeanDefinitions(beanFactory); this.beanFactory = beanFactory; } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
继续看loadBeanDefinitions(beanFactory)方法,实现方法在父类AbstractXmlApplicationContext中
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { //为指定beanFactory创建XmlBeanDefinitionReader XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); //对beanDefinitionReader进行环境变量的设置 beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); //对BeanDefinitionReader进行设置,可以覆盖 initBeanDefinitionReader(beanDefinitionReader); //(关键)使用XmlBeanDefinitionReader的loadBeanDefinitions方法进行配置文件的加载及注册 loadBeanDefinitions(beanDefinitionReader); }
创建了XmlBeanDefinitionReader读取器,作为参数调用loadBeanDefinitions()方法,最终读取器的loadBeanDefinitions()被调用
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { …… //将资源文件转换为io流 try (InputStream inputStream = encodedResource.getResource().getInputStream()) { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //真正开始读取bean return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } …… }
这一步完成了定位阶段,开始加载bean,继续一直调用直到registerBeanDefinitions()方法
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { //创建读取文件并加载Bean的类 BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); //加载Bean documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; }
执行了BeanDefinitionDocumentReader接口的registerBeanDefinitions()方法,进行Bean的解析和注册操作
进入实现类DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions()方法
protected void doRegisterBeanDefinitions(Element root) { …… preProcessXml(root); //使用spring的Bean规则解析元素节点 parseBeanDefinitions(root, this.delegate); postProcessXml(root); …… }
进入parseBeanDefinitions方法,如果发现是Bean节点的话会再进入processBeanDefinition()方法,很关键,这里面就会完成Bean的解析和注册
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //(核心)最终会调用BeanDefinitionParserDelegate这个辅助操作实现类的parseBeanDefinitionElement()方法进行Bean解析 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { //(核心)向spring ioc容器中注册解析得到的Bean定义,这是Bean定义向ioc容器注册的入口 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
parseBeanDefinitionElement()解析方法是从document中解析xml并得到Bean的定义
然后执行BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())方法注册Bean到容器,这里的getRegistry()拿到的其实就是最开始创建Reader读取器的时候设置过的ioc容器(new XmlBeanDefinitionReader(beanFactory)),作为第二个入参传入了registerBeanDefinition()方法
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { //获取Bean的名字 String beanName = definitionHolder.getBeanName(); //registry的实现其实是DefaultListableBeanFactory,注册Bean registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); //注册Bean的别名 String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } }
最后来看一下DefaultListableBeanFactory容器的registerBeanDefinition()是如何进行Bean的注册的
不贴代码了,最终执行了this.beanDefinitionMap.put(beanName, beanDefinition);将Bean添加到了一个ConcurrentHashMap中
2)准备工作,配置ioc容器的特性
查看prepareBeanFactory()方法
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //设置容器的类加载器为当前上下文 beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //增加一个用来给继承了Aware的类设置上下文的前置处理器 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //忽略Aware类 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); //自动装配的特殊规则,这样可以通过autowired的方式拿到ApplicationContext的实例 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); //增加一个用来在Bean(ApplicationListener)销毁之前从ApplicationEventMulticaster(事件广播器)中提前删除的后置处理器 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); //增加对AspectJ的支持 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } //将相关环境变量及属性注册以单例模式注册,environment,systemProperties,systemEnvironment if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
prepareBeanFactory()方法完成了一些ioc容器特性的设置,增加了两个Bean处理器
postProcessBeanFactory()空实现做扩展
invokeBeanFactoryPostProcessors()激活各种BeanFactory处理器
registerBeanPostProcessors()注册Bean处理器
initMessageSource()初始化Message源,国际化
initApplicationEventMulticaster()初始化应用消息广播器
onRefresh()空实现,让子类初始化其他Bean
registerListeners()查找所有监听器,注册到消息广播器中
3)收尾工作,完成ioc容器初始化
进入finishBeanFactoryInitialization()方法,然后进入beanFactory.preInstantiateSingletons()方法(在DefaultListableBeanFactory中)
public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } //获取容器内所有bean名称 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); //遍历所有bean for (String beanName : beanNames) { //很经典的一句,通过递归将BeanDefinition所有父类的属性和方法合并到一起,得到RootBeanDefinition返回 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //如果不是抽象类,如果是单例,如果不是懒加载 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //如果是FactoryBean的类 if (isFactoryBean(beanName)) { //先getBean创建这个FactoryBean(BeanName前面加了&) Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } //如果是SmartFactoryBean且不是懒加载的话需要立刻创建这个FactoryBean if (isEagerInit) { getBean(beanName); } } } else { //创建Bean getBean(beanName); } } } //如果Bean实例实现了SmartInitializingSingleton接口就执行它的afterSingletonsInstantiated()方法,在Bean实例化完成后执行某些操作 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
然后进入最最最核心的getBean()和doGetBean()方法
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { //通过别名得到最终的名字 String beanName = transformedBeanName(name); Object bean; //先尝试获取Bean Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { //若条件为true,表示这个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 + "'"); } } //简单理解就是处理FactoryBean的getObject()方法 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { //原型对象不允许循环创建,如果是原型对象正在创建,那就抛异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //这一步也是必须要做的,若存在父容器,得看看父容器是否实例化过它了。避免被重复实例化(若父容器被实例化,就以父容器的为准) BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } //确认是否已经创建,创建了就加入alreadyCreated重 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //确认是否是抽象类 checkMergedBeanDefinition(mbd, beanName, args); //@dependsOn属性可以控制Bean的初始化顺序 String[] dependsOn = mbd.getDependsOn(); 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的相互依赖关系到2个map registerDependentBean(dep, beanName); try { //先创建依赖Bean的实例 getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } //从这里开始就真的要创建这个Bean的实例了 if (mbd.isSingleton()) { //也是一样先尝试从缓存去获取,如果没有就用createBean()方法去创建 sharedInstance = getSingleton(beanName, () -> { try { //这是创建Bean的核心方法,非常重要 return createBean(beanName, mbd, args); } catch (BeansException ex) { //执行失败就销毁Bean,销毁一条龙 destroySingleton(beanName); throw ex; } }); //处理FactoryBean的情况 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //创建原型Bean(每次用到都会创建) else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { //加入正在创建Prototype列表 beforePrototypeCreation(beanName); //创建Bean prototypeInstance = createBean(beanName, mbd, args); } finally { //移除正在创建Prototype列表 afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } //其他情况,类似 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); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } //如果需要类型转换的话就转换,一般用不到 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException 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; }
然后看一下2个getSingleton()和createBean()方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) { //从一级缓存中找 Object singletonObject = this.singletonObjects.get(beanName); //如果没找到并且Bean正在创建,才会进入二级和三级缓存中寻找 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); //如果二级缓存中没有并且spring允许循环依赖(默认为true),就进入三级缓存中寻找 if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); //将找到的Bean从三级缓存中放入二级缓存 this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
三个缓存的相爱相杀
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) { //如果Bean正在被销毁就抛异常 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 (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } //如果不排除创建检查,就将Bean加入到正在创建singletonsCurrentlyInCreation的map中 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 ex) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } //从正在创建singletonsCurrentlyInCreation的map中移除 afterSingletonCreation(beanName); } if (newSingleton) { //如果创建完成就从二、三级缓存中移除,加入一级缓存,加入已注册Bean的列表 addSingleton(beanName, singletonObject); } } return singletonObject; } }
这个getSingleton()相当于对createBean()方法执行前后做了一些处理,如果一级缓存中没有Bean就进行createBean()
再看一下createBean(),是由子类AbstractAutowireCapableBeanFactory去实现的
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; //确保对应BeanClass完成解析 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } //解析<lookup-method name="getFruit" bean="bananer"/>类似这种方式的依赖注入,不常用 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //关键方法,给BeanPostProcessors一个机会来返回一个代理对象代替目标对象,动态代理就是在这里实现的 //容器里所有的InstantiationAwareBeanPostProcessors实例都会在此处生效,进行前置处理 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { //好了,又是一个核心逻辑,创建Bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
有resolveBeforeInstantiation()前置处理方法和doCreateBean()方法要讲,先看resolveBeforeInstantiation()
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; //判断这个Bean定义是否需要前置处理 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { //不是构造出的内部类并且有前置处理器 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { //执行前置实例化方法,给用户一个生成代理对象的机会 //处理器是遍历执行的,只要有一个result为null,后面就不遍历了,所以顺序很重要,可以用@OrderId设置 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { //如果得到了对象,就执行后置初始化方法 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } //如果Bean实例化了就设置 mbd.beforeInstantiationResolved = (bean != null); } return bean; }
在Bean要开始实例化、属性赋值、初始化之前,执行InstantiationAwareBeanPostProcessor处理器的前置实例化方法和后置初始化方法(可能,如果有的话就跳过了后置实例化方法和前置初始化方法)
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { //用BeanWrapper来持有创建出来的Bean对象 BeanWrapper instanceWrapper = null; //如果是单例的话,则先把缓存中的同名bean清除(同名的) if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //关键了,这里就是Bean的实例化,Bean创建的第一步 //实际创建的交给createBeanInstance来完成,包装成BeanWrapperImpl类 instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { //主要是处理@PostConstruct,@Autowire,@Value,@Resource,@PreDestory等这些注解 //注解都会实现MergedBeanDefinitionPostProcessor接口 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } //如果是单例模式、允许循环依赖、正在进行Bean创建 boolean earlySingletonExposure = (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就是为了处理循环依赖,将Bean放入三级缓存 //getEarlyBeanReference很关键,用到了SmartInstantiationAwareBeanPostProcessor,允许这层进行扩展处理 //这个方法也是写入singletonFactories三级缓存的地方 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } //这个Bean是最终要返回的对象 Object exposedObject = bean; try { //又是很关键的一步,进行Bean的属性赋值,在这里完成依赖注入,Bean创建的第二步 populateBean(beanName, mbd, instanceWrapper); //叒是很关键的一步,进行Bean的初始化,Bean创建的最后一步 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); } } //继续解决循环依赖问题,用到前面的earlySingletonExposure1结果 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } 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."); } } } } //如果有需要,就注册DisposableBean,这样Bean销毁的时候此种后置处理器也会生效了 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
createBeanInstance()方法生成了Bean的BeanWrapperImpl实例对象,Bean的实例化,Bean创建的第一步
populateBean()方法进行了Bean的属性赋值(包括@Autowired等依赖属性注入),Bean创建的第二步
initializeBean()方法进行Bean的初始化,Bean创建的最后一步
后续不跟代码了,可以看这里
5、如何解决循环依赖
1)spring循环依赖总结
spring能解决单例的属性注入(setter方法注入)循环依赖
spring不能解决构造器注入循环依赖和多例的属性注入循环依赖
2)spring怎么解决循环依赖?
spring解决循环依赖的方式是通过缓存队列提前暴露的还未完成的bean对象,如果对象A在属性赋值阶段需要注入一个依赖自己的对象B,那在对象B创建时就可以在缓存队列中找到对象A的引用,完成对象的创建,不然就会一直循环创建下去造成内存溢出
3)为什么spring不能解决构造器注入循环依赖?
spring创建Bean的步骤是实例化、属性赋值、初始化,是在属性赋值阶段解决循环依赖的,构造器注入相当于将前两步同时进行,还没有完成实例化就需要进行属性赋值,这样spring没法通过提前暴露未完成bean的方式来解决循环依赖
4)为什么spring不能解决多例属性注入循环依赖?
单例的情况每个对象是固定的,处理循环引用时getBean可以拿到同一个提前暴露对象的引用,而多例的情况下每次getBean都会创建一个新的对象,无法确定引用哪一个
5)我们怎么解决spring解决不了的循环依赖?
我们可以解决的是构造器注入循环依赖的情况:重新设计、合理分层、尽量不要使用构造器注入,使用属性注入或setter方法注入
6)为什么需要三级缓存?
如果没有aop的话二级缓存就可以解决循环依赖的问题,有aop的话为了避免每次singleFactory.getObject()方法每次都产生一个新的代理对象,所以需要另一个缓存来保存产生的代理对象
所以最后的三级缓存作用分别是:一级缓存存放完全初始化、成品的bean,二级缓存存放半成品的bean或bean的代理对象,三级缓存存放ObjectFactory,如果是bean被代理getObject返回代理对象,不然就返回原bean对象
6、ioc容器扩展点
BeanFactoryPostProcessor、BeanPostProcessor,分别在构建 BeanFactory 和构建 Bean 对象时调用
BeanDefinitionRegistryPostProcessor 、InstantiationAwareBeanPostProcessor?
InitializingBean、DisposableBean,分别是在 Bean 实例创建和销毁时被调用
FactoryBean,构建 Bean 对象时调用,通常是用来创建比较复杂的bean,一般的bean 直接用xml配置即可,但如果一个bean的创建过程中涉及到很多其他的bean 和复杂的逻辑,用xml配置比较困难,这时可以考虑用FactoryBean
7、aop
8、事务
二、spring mvc
1、spring mvc的启动流程
2、一次请求调用的流程
3、如何自定义注解?
三、spring boot
1、spring模块驱动的实现方式?
引入模块化驱动可以简化装配步骤,屏蔽模块中组件集合装配的细节
spring实现@Enable模块有两种方式
基于@Import注解,通过@Import注解导入标注了@Configuration的配置类
基于接口编程,实现ImportSelector接口的selectImports方法,或者ImportBeanDefinitionRegistrar接口重写registerBeanDefinitions方法,通过 BeanDefinitionRegistry注册和该模块相关的组件
2、spring boot的自动装配
spring boot的启动类@SpringBootApplication注解包含了一个@EnableAutoConfiguration注解,通过这个注解引入了自动装配模块
-- 在这个注解中@AutoConfigurationPackage注解负责扫描当前主类所在包和依赖包下的bean,
在这个注解中Import了AutoConfigurationImportSelector类,这个类实现了selectImports接口,
-- (貌似其实不会)首先会从当前的spring-boot-autoconfigure包的META-INF下的元数据json中加载properties配置项,然后在
它会在classpath下每个Jar包中搜寻所有META-INF/spring.factories配置文件,spring.factories文件中的AutoConfiguration配置类类名集合,将类名去重、排除、过滤,最终返回自动装配的类名集合,
这个方法会在ioc启动时,容器的refresh方法的invokeBeanFactoryPostProcessors这一步,被ConfigurationClassPostProcessor创建的ConfigurationClassParser类用到,完成配置类的装配
spring.factories配置的方式是一种类似SPI的扩展机制(为某些接口寻找服务实现的机制,往往去约定的位置读取配置发现需要加载的实现类)
3、spring boot的启动流程
准备阶段会做SpringApplication类的初始化,判断web应用类型、加载应用上下文初始化类,从所有的META-INF/spring.factories资源中获取ApplicationContextInitializer的实现类(这些类是在在ConfigurableApplicationContext的refresh() 方法调用之前做一些初始化工作)、加载应用事件监听器。获取ApplicationListener的实现类(主要功能是另起一个后台线程触发那些耗时的初始化,包括验证器、消息转换器等,spring boot支持的事件主要有环境构建完成时、上下文构建完成时、上下文加载完成时、上下文刷新完成并启动时、启动完成时、启动失败时,在下一步运行阶段的相应时刻就会推送事件)
运行阶段会先从所有的META-INF/spring.factories资源中获取SpringApplicationRunListeners事件监听器,然后设置环境信息、根据web类型创建上下文(判断创建普通容器还是web容器)、准备上下文、刷新容器(完成bean的加载)、最后执行Runner的实现类完成一些自定义初始化,期间穿插事件方法的回调
4、嵌入式容器自动装配流程
在SpringApplication类启动的run()方法里会根据web类型创建应用上下文,然后在容器的refresh()方法中,在invokeBeanFactoryPostProcessors()这步执行ConfigurationClassPostProcessor类的扩展,读取spring.factories并加载ServletWebServerFactoryAutoConfiguration类,这个类通过@Import导入了3个用来创建web容器工厂类内部类(有tomcat、jetty和undertow),如果存在maven依赖就会创建相应的web容器工厂类
之后执行容器的onRefresh()方法,web应用上下文作为子类重写了这个方法,找到servlet web容器工厂Bean,创建内嵌的tomcat服务
最后在容器的finishRefresh()时执行web服务的启动webServer.start()