本帖最初由 进修派 于 2020-12-3 21:22 编纂
目次Spring流程Debug 办法1:prepareRefresh() => 筹办事情 办法2:obtainFreshBeanFactory() => 得到一个革新的bean容器 办法3:prepareBeanFactory(beanFactory) => 筹办(初初化)Bean工场 办法4:postProcessBeanFactory(beanFactory) => 后置加强Bean(扩大完成) 办法5:invokeBeanFactoryPostProcessors(beanFactory) => 施行BFPP 办法6:registerBeanPostProcessors(beanFactory) => 注册BPP 办法7:initMessageSource() => 国际化设置 办法8:initApplicationEventMulticaster() => 初初化使用法式的多波器战播送器 办法9:onRefresh() => 预留给子类做扩大 办法10:registerListeners() => 注册监听器 办法11:finishBeanFactoryInitialization(beanFactory) => 真例化一切单例工具 办法12:finishRefresh() => 完成革新 办法13:resetCommonCaches() => 缓存重置 1.1 Spring测试情况拆建 1.2 Debug容器创立历程 1.3 AbstractApplicationContext的refresh()包罗的13个办法阐发
Spring流程Debug1.1 Spring测试情况拆建Spring模块概览,绿色是模块,Spring终年夜模块,玄色暗示该模块包罗的jar包(组件)。比方我们念要用IOC容器,也便是绿色的CoreContainer,我们需求导进Beans,Core,Context,SpEL(spring-expression)四个包。 Spring模块概览Test:测试相干 Core Container:IOC容器 AOP:里背切里编程 Aspects:切里 Instrumenttation:跟JDK联系关系,普通不消 Messaging?息效劳,普通不消 Data Access/Integration:数据会见取散成(JDBC会见,Transaction事件,ORM工具干系映照,OXM战XML映照普通不消,JMS为Java动静效劳Java-message-service普通不消) Web:Web效劳(WebSocket收集通讯和谈,Servlet, Web,Portlet普通不消)
最徒擦的方法,是间接导进Spring-Framework。可是能够导进没必要要的包,招致项目挨包后比力年夜
因为Spring-Content中的ApplicationContent是全部IOC的进口。我们导进Spring-context包便可
-
- <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>5.2.3.RELEASE</version>
- </dependency>
赶钙代码
我们导进spring-content后,默许会导进该组件的依靠jar,spring-content蹬鲢的依靠能够看到,实践上我们是导进了Core Container模块
-
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- <version>5.2.3.RELEASE</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-beans</artifactId>
- <version>5.2.3.RELEASE</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>5.2.3.RELEASE</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-expression</artifactId>
- <version>5.2.3.RELEASE</version>
- <scope>compile</scope>
- </dependency>
- </dependencies>
赶钙代码
新建Spring设置文件spring.xml:
-
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
-
- <!--注册一个工具,spring回主动创立那个工具-->
- <!--
- 一个bean标签便暗示一个工具
- id:那个工具的独一标识
- class:注册工具的完整限制名
- -->
- <bean id="hello" class="com.xiaodai.service.Hello">
- <!--利用property标签给工具的属性赋值
- name:暗示属性的称号
- value:暗示属性的值
- -->
- <property name="id" value="1"></property>
- <property name="name" value="zhangsan"></property>
- <property name="age" value="18"></property>
- </bean>
- </beans>
赶钙代码
编写测试类:
-
- import com.xiaodai.service.Hello;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
-
- public class Test {
-
- public static void main(String[] args) {
- ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
- Hello hello = applicationContext.getBean("hello", Hello.class);
- System.out.println(hello.getName());
-
- }
-
- }
赶钙代码
1.2 Debug容器创立历程从测试类的new ClassPathXmlApplicationContext("spring.xml")开端debug,进进ClassPathXmlApplicationContext,能够看到: -
- public ClassPathXmlApplicationContext(
- String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
- throws BeansException {
-
- super(parent);
- // 设置设置文件途径
- setConfigLocations(configLocations);
- if (refresh) {
- // 中心步调
- refresh();
- }
- }
赶钙代码
减载设置文件后,进进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.
- /**
- * 得到一个革新的bean容器,本质便是获得工场。
- * 减载xml等设置文件,用该文件发生的BeanDefinition去创立一个工场
- **/
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
-
- // Prepare the bean factory for use in this context.
- /**
- * 筹办bean工场
- **/
- prepareBeanFactory(beanFactory);
-
- try {
- // Allows post-processing of the bean factory in context subclasses.
- // 后置加强,便利扩大
- postProcessBeanFactory(beanFactory);
-
- // Invoke factory processors registered as beans in the context.
- // 真例化而且施行BeanFactoryPostProcessors
- invokeBeanFactoryPostProcessors(beanFactory);
-
- // Register bean processors that intercept bean creation.
- // 真例化而且注册一切的BeanPostProcessor
- 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) {
- 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();
- }
- }
- }
赶钙代码
1.3 AbstractApplicationContext的refresh()包罗的13个办法阐发分离概览图一个一个办法阐发: Bean工场真例化Bean概览图办法1:prepareRefresh() => 筹办事情筹办革新,做一些最根本的筹办化事情 -
- protected void prepareRefresh() {
- // Switch to active.
- // 设置开端工夫
- this.startupDate = System.currentTimeMillis();
- // 封闭形态设置为false
- this.closed.set(false);
- // 活泼形态设置为true
- this.active.set(true);
-
- // 挨印日记
- if (logger.isDebugEnabled()) {
- if (logger.isTraceEnabled()) {
- logger.trace("Refreshing " + this);
- }
- else {
- logger.debug("Refreshing " + getDisplayName());
- }
- }
-
- // Initialize any placeholder property sources in the context environment.
- // 初初化属性资本
- initPropertySources();
-
- // Validate that all properties marked as required are resolvable:
- // see ConfigurablePropertyResolver#setRequiredProperties
- // 获得情况疑息,考证属性疑息
- getEnvironment().validateRequiredProperties();
-
- // Store pre-refresh
- // 存储预革新的一些使用疑息的监听器
- ApplicationListeners...
- if (this.earlyApplicationListeners == null) {
- this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
- }
- else {
- // Reset local application listeners to pre-refresh state.
- this.applicationListeners.clear();
- this.applicationListeners.addAll(this.earlyApplicationListeners);
- }
-
- // Allow for the collection of early ApplicationEvents,
- // to be published once the multicaster is available...
- // 创立一些监听器变乱的汇合
- this.earlyApplicationEvents = new LinkedHashSet<>();
- }
赶钙代码
总结:1.设置启动变乱 2.设置封闭活泼的形态 3.获得情况工具并设置属性值 4.设置监听器和需求公布变乱的汇合。搜刮公家号 Java条记虾,复兴“后端口试“收您一份口试题宝典.pdf 主要的面:
|