<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>archive</title><link>https://archive-w.netlify.app/doc/framework/spring/springcore/</link><description>Recent content on archive</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://archive-w.netlify.app/doc/framework/spring/springcore/index.xml" rel="self" type="application/rss+xml"/><item><title/><link>https://archive-w.netlify.app/doc/framework/spring/springcore/00_spring_startup/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://archive-w.netlify.app/doc/framework/spring/springcore/00_spring_startup/</guid><description>&lt;ul>
&lt;li>
&lt;h2 id="introstartup-process">
 Intro(Startup Process)
 &lt;a class="anchor" href="#introstartup-process">#&lt;/a>
&lt;/h2>
&lt;p class="tip">&lt;code>spring.version = 4.3.7.RELEASE&lt;/code>&lt;/p>
&lt;p style="text-align: center;">&lt;img src="https://archive-w.netlify.app/.images/doc/framework/spring/00-spring-startup/ss-001.png" alt="" width="100%">&lt;/p>
&lt;div class="alert callout tip">&lt;p class="title">&lt;span class="icon icon-tip">&lt;/span> Tip &lt;/p>&lt;p> &lt;code>1.)&lt;/code> &lt;code>ApplicationContext&lt;/code>继承了&lt;code>BeanFactory&lt;/code>接口，在内部实现中采用委托的方式调用正真的beanfactory.&lt;/p>
&lt;/p>&lt;/div>
&lt;ul>
&lt;li>
&lt;h3 id="解析流程">
 解析流程
 &lt;a class="anchor" href="#%e8%a7%a3%e6%9e%90%e6%b5%81%e7%a8%8b">#&lt;/a>
&lt;/h3>
&lt;p class="warn">&lt;code>1).&lt;/code> 以&lt;code>ClassPathXmlApplicationContext&lt;/code>为例，新建一个应用上下文：&lt;code>new ClassPathXmlApplicationContext(&amp;quot;_framework/spring/res/factory-bean.xml&amp;quot;);&lt;/code>
&lt;br>&lt;span style='padding-left:2.8em' />&lt;img src="https://archive-w.netlify.app/.images/doc/framework/spring/00-spring-startup/ss-01.png" alt="" width="70%">
&lt;br>&lt;br>&lt;code>2).&lt;/code> 紧接着通过&lt;code>super(parent)&lt;/code>调用父类构造器，一直往上传，直到&lt;code>AbstractApplicationContext&lt;/code>,调用自己无参构造器&lt;code>this();&lt;/code>后，使用&lt;code>setParent(parent);&lt;/code>设置父属性。
&lt;br>&lt;span style='padding-left:2.8em' />在&lt;code>this()&lt;/code>内部获取一个&lt;code>PathMatchingResourcePatternResolver()&lt;/code>.
&lt;br>&lt;br>&lt;code>3).&lt;/code> 然后是设置配置文件位置&lt;code>setConfigLocations(configLocations);&lt;/code>,对于每一个配置文件，都会通过&lt;code>getEnvironment()&lt;/code>获取环境变量&lt;code>StandardEnvironment&lt;/code>对象解决(&lt;del>配置文件&lt;/del>)配置文件路径中的占位符。
&lt;br>&lt;br>&lt;code>4).&lt;/code> 接下来进入主题&lt;code>AbstractApplicationContext#refresh();&lt;/code>
&lt;br>&lt;span style='padding-left:2.8em' />&lt;img src="https://archive-w.netlify.app/.images/doc/framework/spring/00-spring-startup/ss-02.png" alt="" width="70%" height="550p">&lt;/p>
&lt;ul>
&lt;li>
&lt;h4 id="refresh">
 refresh()
 &lt;a class="anchor" href="#refresh">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>
&lt;h5 id="01-preparerefresh">
 01). prepareRefresh()
 &lt;a class="anchor" href="#01-preparerefresh">#&lt;/a>
&lt;/h5>
&lt;p class="warn">
&lt;img src="https://archive-w.netlify.app/.images/doc/framework/spring/00-spring-startup/ss-03.png" alt="" width="59%"> &lt;img src="https://archive-w.netlify.app/.images/doc/framework/spring/00-spring-startup/ss-04.png" alt="" width="34%">
&lt;br>对于刷新这个上下文做准备。记录启动时间，关闭状态，激活状态。
&lt;br>以及留给子类去初始化propertySource的方法&lt;code>initPropertySources();&lt;/code>，
&lt;br>获取环境并校验通过&lt;code>ConfigurablePropertyResolver#setRequiredProperties&lt;/code>设置的必需属性，委托给 &lt;strong>AbstractPropertyResolver&lt;/strong> 去执行校验。
&lt;br>另外准备一个保存&lt;strong>应用事件&lt;/strong>的set容器。&lt;/p>
&lt;/li>
&lt;li>
&lt;h5 id="02-obtainfreshbeanfactory">
 02). obtainFreshBeanFactory()
 &lt;a class="anchor" href="#02-obtainfreshbeanfactory">#&lt;/a>
&lt;/h5>
&lt;p class="warn">
&lt;img src="https://archive-w.netlify.app/.images/doc/framework/spring/00-spring-startup/ss-05.png" alt="" width="49%">
&lt;br>获取一个新的bean工厂。
&lt;br>&lt;br>&lt;code>protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;&lt;/code>由子类去处理。
&lt;br>&lt;img src="https://archive-w.netlify.app/.images/doc/framework/spring/00-spring-startup/ss-06.png" alt="" width="60%">
&lt;br>&lt;br>通过&lt;code>createBeanFactory()&lt;/code>方法new一个 &lt;strong>DefaultListableBeanFactory&lt;/strong> bean工厂
&lt;br>&lt;br>&lt;code>customizeBeanFactory(beanFactory);&lt;/code>根据需要设置bean定义覆盖和循环引用的标志。
&lt;br>&lt;img src="https://archive-w.netlify.app/.images/doc/framework/spring/00-spring-startup/ss-07.png" alt="" width="60%">&lt;/p>
&lt;ul>
&lt;li>
&lt;h6 id="021-loadbeandefinitions">
 02.1). loadBeanDefinitions
 &lt;a class="anchor" href="#021-loadbeandefinitions">#&lt;/a>
&lt;/h6>
&lt;p class="warn">&lt;code>loadBeanDefinitions(beanFactory);&lt;/code>加载bean定义，是抽象类&lt;code>AbstractRefreshableApplicationContext&lt;/code>中定义的方法，由子类&lt;code>AbstractXmlApplicationContext&lt;/code>去实现。
&lt;br>&lt;img src="https://archive-w.netlify.app/.images/doc/framework/spring/00-spring-startup/ss-08.png" alt="" width="60%">
&lt;br>&lt;br>创建beanDefinitionReader，传递benafactory给父类&lt;code>AbstractBeanDefinitionReader&lt;/code>初始化 &lt;strong>resourceLoader&lt;/strong> 和 &lt;strong>environment&lt;/strong> 属性。但是在后续步骤中，使用了applicationContext的环境覆盖了自己刚才初始化的，包括ResourceLoader也一样。&lt;span style='color:blue'>并且在reader对象中保存当前beanfactory，方便后续进行操作。&lt;/span>
&lt;br>&lt;br>&lt;strong>initBeanDefinitionReader(beanDefinitionReader)&lt;/strong> ，初始化reader属性，比如设置validate=true.
&lt;br>&lt;strong>loadBeanDefinitions(beanDefinitionReader)&lt;/strong> ，使用reader从配置文件中加载beandefinitions到beanfactory中。&lt;/p></description></item><item><title/><link>https://archive-w.netlify.app/doc/framework/spring/springcore/01_factory_bean/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://archive-w.netlify.app/doc/framework/spring/springcore/01_factory_bean/</guid><description>&lt;ul>
&lt;li>
&lt;h2 id="introfactorybean">
 Intro(FactoryBean)
 &lt;a class="anchor" href="#introfactorybean">#&lt;/a>
&lt;/h2>
&lt;p class="warn">&lt;code>spring.version = 4.3.7.RELEASE&lt;/code>&lt;/p>
&lt;ul>
&lt;li>
&lt;h3 id="准备编码">
 准备编码
 &lt;a class="anchor" href="#%e5%87%86%e5%a4%87%e7%bc%96%e7%a0%81">#&lt;/a>
&lt;/h3> &lt;div class="docsify-example-panels"> &lt;div class="docsify-example-panel left-panel"style="max-width: 50%; width: 50%;">
&lt;div class="outer yosemite">&lt;div class="dot red">&lt;/div>&lt;div class="dot amber">&lt;/div>&lt;div class="dot green">&lt;/div>&lt;/div>
&lt;div class="code-toolbar">&lt;pre data-lang="java" data-line="" class="language-java line-numbers" style="max-height: none">&lt;code class="language-java">// 创建普通bean
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Tool {

 private int id;

}

// 创建工厂
@Data
public class ToolFactory implements FactoryBean&amp;lt;Tool&amp;gt; {

 private int factoryId;

 private int toolId;

 @Override
 public Tool getObject() throws Exception {
 return new Tool(toolId);
 }

 @Override
 public Class&amp;lt;?&amp;gt; getObjectType() {
 return Tool.class;
 }

 @Override
 public boolean isSingleton() {
 return false;
 }
}
&lt;/code>&lt;/pre>&lt;/div>&lt;/div>
 &lt;div class="docsify-example-panel right-panel"style="max-width: 50%; width: 50%;">
&lt;div class="outer yosemite">&lt;div class="dot red">&lt;/div>&lt;div class="dot amber">&lt;/div>&lt;div class="dot green">&lt;/div>&lt;/div>
&lt;div class="code-toolbar">&lt;pre data-lang="xml" data-line="" class="language-xml line-numbers" style="max-height: none">&lt;code class="language-xml">&amp;lt;!-- factory-bean.xml --&amp;gt;

&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;
 xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
 xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&amp;quot;&amp;gt;

 &amp;lt;!-- FactoryBean work process --&amp;gt;
 &amp;lt;bean id=&amp;quot;toolFB&amp;quot; class=&amp;quot;_framework.spring.factory_bean.beans.ToolFactory&amp;quot;&amp;gt;
 &amp;lt;property name=&amp;quot;factoryId&amp;quot; value=&amp;quot;9090&amp;quot; /&amp;gt;
 &amp;lt;property name=&amp;quot;toolId&amp;quot; value=&amp;quot;2&amp;quot; /&amp;gt;
 &amp;lt;/bean&amp;gt;

&amp;lt;/beans&amp;gt;
&lt;/code>&lt;/pre>&lt;/div>
&lt;div class="outer yosemite">&lt;div class="dot red">&lt;/div>&lt;div class="dot amber">&lt;/div>&lt;div class="dot green">&lt;/div>&lt;/div>
&lt;div class="code-toolbar">&lt;pre data-lang="java" data-line="" class="language-java line-numbers" style="max-height: none">&lt;code class="language-java">public class SpringFactoryBeanTest {

 public static void main(String[] args) {

 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(&amp;quot;_framework/spring/res/factory-bean.xml&amp;quot;);
 ToolFactory fb = applicationContext.getBean(&amp;quot;&amp;amp;toolFB&amp;quot;, ToolFactory.class);
 Tool tool1 = applicationContext.getBean(Tool.class);
 Tool tool2 = applicationContext.getBean(Tool.class);
 System.out.println();
 applicationContext.destroy();

 }

}
&lt;/code>&lt;/pre>&lt;/div>&lt;/div>&lt;/div>

&lt;/li>
&lt;li>
&lt;h3 id="解析流程">
 解析流程
 &lt;a class="anchor" href="#%e8%a7%a3%e6%9e%90%e6%b5%81%e7%a8%8b">#&lt;/a>
&lt;/h3>
&lt;p class="warn">&lt;code>1).&lt;/code> 初始化bean对象：在&lt;code>refresh()&lt;/code>里面通过&lt;code>obtainFreshBeanFactory()&lt;/code>方法创建扫描到beanDefinition的顶级工厂。然后通过方法&lt;code>finishBeanFactoryInitialization(beanFactory);&lt;/code>实例化所有非懒加载的所有单例bean,此处就包含这个工厂bean对象。&lt;/p></description></item><item><title/><link>https://archive-w.netlify.app/doc/framework/spring/springcore/spring-bak/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://archive-w.netlify.app/doc/framework/spring/springcore/spring-bak/</guid><description>&lt;h2 id="spring-是什么">
 spring 是什么
 &lt;a class="anchor" href="#spring-%e6%98%af%e4%bb%80%e4%b9%88">#&lt;/a>
&lt;/h2>
&lt;blockquote>
&lt;p>Spring是一个轻量级的IoC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架，目的是用于简化企业应用程序的开发，它使得开发者只需要关心业务需求。&lt;/p>
&lt;/blockquote>
&lt;h2 id="spring-优点">
 spring 优点
 &lt;a class="anchor" href="#spring-%e4%bc%98%e7%82%b9">#&lt;/a>
&lt;/h2>
&lt;blockquote>
&lt;p>低入侵，减少代码耦合，支持一些通用任务（鉴权，日志，事务等）的集中管理，对其他一些框架提供集成支持&lt;/p>
&lt;/blockquote>
&lt;h2 id="spring-ioc-理解">
 spring IOC 理解
 &lt;a class="anchor" href="#spring-ioc-%e7%90%86%e8%a7%a3">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>IOC
&lt;blockquote>
&lt;p>IOC(Inversion of control. 控制反转)，将bean对象的控制权交由spring去管理。
其中包括bean对象的创建与销毁，bean对象之间的依赖关系等。简单来讲，就是对象不用我们去new了，而是框架帮我们使用反射的方式去创建。
用户只需要在使用的时候注入即可。&lt;/p>
&lt;/blockquote>
&lt;/li>
&lt;li>DI
&lt;blockquote>
&lt;p>DI (dependency inject ,依赖注入)，程序运行期间如果发现对象需要依赖其他的对象。就会通过反射的方式自动处理依赖关系。
反射的功能就是在程序运行期间动态的生成对象，执行对象的方法，改变对象的属性等功能。&lt;/p>
&lt;/blockquote>
&lt;/li>
&lt;/ul>
&lt;h2 id="spring-aop-理解">
 spring AOP 理解
 &lt;a class="anchor" href="#spring-aop-%e7%90%86%e8%a7%a3">#&lt;/a>
&lt;/h2>
&lt;blockquote>
&lt;p>AOP 面向切面编程。作为面向对象的一种补充，用于将那些与业务无关，但却对多个对象产生影响的公共行为和逻辑，抽取并封装为一个可重用的模块，这个模块被命名为“切面”（Aspect），减少系统中的重复代码，降低了模块间的耦合度，提高系统的可维护性。可用于权限认证、日志、事务处理。
编程中使用cglib和jdk两种动态代理来实现。&lt;/p>
&lt;/blockquote>
&lt;h2 id="beanfactory-和-applicationcontext区别">
 BeanFactory 和 ApplicationContext区别
 &lt;a class="anchor" href="#beanfactory-%e5%92%8c-applicationcontext%e5%8c%ba%e5%88%ab">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>MessageSource
&lt;blockquote>
&lt;p>用于消息资源国际化&lt;/p>
&lt;/blockquote>
&lt;/li>
&lt;li>ResourcePatternResolver
&lt;blockquote>
&lt;p>在上一篇中我们介绍了Resource接口，它的出现是为了解决spring方便访问各种配置信息。
但Resource接口有一个问题，就是如果我们要访问同一个路径下的所有符合条件的配置，如果用Resource接口则会比较麻烦，因为它不支持通配符方式的文件读取，所以要将读取的配置文件名称全部写出来才可以。
spring为了解决这个问题，于是新定义了一个新接口，并实现了该接口特有的特性，也就是支持类似


 &lt;a href="https://ant.apache.org/manual/dirtasks.html#patterns" rel="noopener" target="_blank">Ant风格&lt;/a>的通配符&lt;/p>
&lt;/blockquote>
&lt;/li>
&lt;li>ApplicationEventPublisher
&lt;blockquote>
&lt;p>时间发布器&lt;/p>
&lt;/blockquote>
&lt;/li>
&lt;li>EnvironmentCapable
&lt;blockquote>
&lt;p>提供环境处理能力，getEnvironment()返回的 Environment 不可配置。所以在ConfigurableApplicationContext重新定义getEnvironment()并缩小签名以返回一个ConfigurableEnvironment。在此之前 环境对象 是只读的。&lt;/p>
&lt;/blockquote>
&lt;/li>
&lt;/ul>
&lt;h2 id="spring-容器启动流程">
 spring 容器启动流程
 &lt;a class="anchor" href="#spring-%e5%ae%b9%e5%99%a8%e5%90%af%e5%8a%a8%e6%b5%81%e7%a8%8b">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>启动流程&lt;/p>
 &lt;details>&lt;summary>代码示例&lt;/summary>
&lt;div class="outer yosemite">&lt;div class="dot red">&lt;/div>&lt;div class="dot amber">&lt;/div>&lt;div class="dot green">&lt;/div>&lt;/div>
&lt;div class="code-toolbar">&lt;pre data-lang="java" data-line="" class="language-java line-numbers" style="max-height: none">&lt;code class="language-java">@Override
public void refresh() throws BeansException, IllegalStateException {
 synchronized (this.startupShutdownMonitor) {
 // Prepare this context for refreshing.
 // 准备这个上下文以便刷新，设置它的启动日期和活动标志，并执行PropertySource属性源的任何初始化。
 prepareRefresh();

 // Tell the subclass to refresh the internal bean factory.
 // DefaultListableBeanFactory beanFactory = createBeanFactory();
 // beanFactory.setSerializationId(getId());
 // customizeBeanFactory(beanFactory);
 // loadBeanDefinitions(beanFactory);
 // 如果开启包扫描，会默认加载6个bd,(根据环境不同，可能数量有变，比如还可能有EJB的) 参见下图
 // class org.springframework.context.annotation.ConfigurationClassPostProcessor
 // class org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
 // class org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
 // class org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
 // CommonAnnotationBeanPostProcessor 是根据 jsr250 加载的。
 // private static final boolean jsr250Present = ClassUtils.isPresent(&amp;quot;javax.annotation.Resource&amp;quot;, AnnotationConfigUtils.class.getClassLoader());
 // class org.springframework.context.event.DefaultEventListenerFactory
 // class org.springframework.context.event.EventListenerMethodProcessor
 // return beanFactory;
 // 一般来说ApplicationContext自己没有实现BeanFactory相关方法，而是委托给自己刚才实例化的属性 beanFactory 来实现BeanFactory效果的。
 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

 // Prepare the bean factory for use in this context.
 // 初始化 beanFactory 相关属性。
 prepareBeanFactory(beanFactory);

 try {
 // Allows post-processing of the bean factory in context subclasses.
 // 让子类继续处理 beanFactory 增加或修改属性。比如WebApplicationContext
 // beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
 // beanFactory.ignoreDependencyInterface(ServletContextAware.class);
 // beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
 // WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
 // WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
 postProcessBeanFactory(beanFactory);

 // Invoke factory processors registered as beans in the context.
 // 调用在上下文中已注册为bean的工厂处理器，来增加或修改属性。
 // 比如ConfigurationClassPostProcessor。创建了一个org.springframework.context.annotation.internalConfigurationAnnotationProcessor对象。
 // 且给beanFactory的属性：beanPostProcessors 增加了一个 ImportAwareBeanPostProcessor。

 // 1027追加注释 
 // 内部逻辑先找 实现了BeanDefinitionRegistryPostProcessor接口的 实例化然后按顺序进行接口调用。因为这个接口继承自BeanFactoryPostProcessor.所以还会对这个接口也进行调用。
 // 然后是其余的BeanFactoryPostProcessor 这个接口 实例化后再按照顺序进行接口调用
 invokeBeanFactoryPostProcessors(beanFactory);

 // Register bean processors that intercept bean creation.
 // 向容器中实例化BeanPostProcessor，并追加到beacFactory的属性：beanPostProcessors中。

 // 1027追加注释 
 // 和上面调用一样，不过这次找的是BeanPostProcessor接口，另外会追加属性 到 beanPostProcessors中。因为这个接口的功能是对Bean的创建进行拦截处理实例用的。而不是修改beanDefinition用的。
 registerBeanPostProcessors(beanFactory);

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

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

 // Initialize other special beans in specific context subclasses.
 // 对于EmbedWebApplicationContext 调用 createEmbeddedServletContainer();
 onRefresh();

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

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

 // Last step: publish corresponding event.
 finishRefresh();
 }
 // ...
 }
}
&lt;/code>&lt;/pre>&lt;/div>
 &lt;/details>
&lt;p>&lt;img src="https://archive-w.netlify.app/.images/doc/framework/spring/xmlac-load-bd.png" alt="" width="65%">&lt;/p></description></item></channel></rss>