简介
spring 是一款轻量级的框架,主要包含的功能有AOP、IOC(DI),包含的模块如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| spring ├── aopalliance-1.0.jar ├── commons-logging-1.2.jar ├── spring-aop-5.2.3.RELEASE.jar ├── spring-aspects-5.2.3.RELEASE.jar ├── spring-beans-5.2.3.RELEASE.jar ├── spring-context-5.2.3.RELEASE.jar ├── spring-context-support-5.2.3.RELEASE.jar ├── spring-core-5.2.3.RELEASE.jar ├── spring-expression-5.2.3.RELEASE.jar ├── spring-instrument-5.2.3.RELEASE.jar ├── spring-jdbc-5.2.3.RELEASE.jar ├── spring-jms-5.2.3.RELEASE.jar ├── spring-messaging-5.2.3.RELEASE.jar ├── spring-orm-5.2.3.RELEASE.jar ├── spring-oxm-5.2.3.RELEASE.jar ├── spring-test-5.2.3.RELEASE.jar └── spring-tx-5.2.3.RELEASE.jar
|
加载流程分析
1.1 新建立maven项目
1 2 3 4 5 6 7 8
| <?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"> <beans> <bean id="messageService" class="com.analyxe.service.impl.MessageServiceImpl"/> </beans> </beans>
|
1 2 3
| public interface MessageService { public String getMessage(); }
|
1 2 3 4 5 6 7
| public class MessageServiceImpl implements MessageService { @Override public String getMessage() { System.out.println("get message ......"); return "MESSAGE"; } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class Main { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); MessageService messageService = (MessageService) context.getBean("messageService"); String message = messageService.getMessage(); System.out.println(message); } }
|
1.2 代码跟踪
下面我们一步一步来代码跟踪
1.2.1 调用应用上下文构造方法
1 2 3 4 5
| public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[]{configLocation}, true, (ApplicationContext)null); }
|
1.2.2 构造方法
1 2 3 4 5 6 7 8
| public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); this.setConfigLocations(configLocations); if (refresh) { this.refresh(); } }
|
3.再看看其调用ClassPathXmlApplicationContext父类构造方法具体是什么
1 2 3
| public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) { super(parent); }
|
4.再看看其调用AbstractXmlApplicationContext父类构造方法具体是什么,它又调用父类
1 2 3
| public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) { super(parent); }
|
5.我们瞧瞧这个AbstractApplicationContext的构造方法
1 2 3 4 5 6 7 8 9 10 11 12
| public AbstractApplicationContext(@Nullable ApplicationContext parent) { this(); this.setParent(parent); }
public AbstractApplicationContext() { this.resourcePatternResolver = getResourcePatternResolver(); }
protected ResourcePatternResolver getResourcePatternResolver() { return new PathMatchingResourcePatternResolver(this); }
|
6.设置AbstractApplicationContext环境配置信息
1 2 3 4 5 6 7 8 9
| public void setParent(@Nullable ApplicationContext parent) { this.parent = parent; if (parent != null) { Environment parentEnvironment = parent.getEnvironment(); if (parentEnvironment instanceof ConfigurableEnvironment) { this.getEnvironment().merge((ConfigurableEnvironment)parentEnvironment); } } }
|
1.2.7 设置加载配置文件
处理加载配置文件路径,见1.2.2中的2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public void setConfigLocations(@Nullable String... locations) { if (locations != null) { Assert.noNullElements(locations, "Config locations must not be null"); this.configLocations = new String[locations.length]; for (int i = 0; i < locations.length; i++) { this.configLocations[i] = resolvePath(locations[i]).trim(); } } else { this.configLocations = null; } }
protected String resolvePath(String path) { return getEnvironment().resolveRequiredPlaceholders(path); }
public ConfigurableEnvironment getEnvironment() { if (this.environment == null) { this.environment = createEnvironment(); } return this.environment; }
protected ConfigurableEnvironment createEnvironment() { return new StandardEnvironment(); }
|
1.2.8 刷新容器(核心)
判断是否需要刷新容器,见1.2.2中的 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); registerBeanPostProcessors(beanFactory); initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); finishBeanFactoryInitialization(beanFactory); finishRefresh(); }catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + ex); } destroyBeans(); cancelRefresh(ex); throw ex; } finally { resetCommonCaches(); } } }
|
1.2.8.1 prepareRefresh (预刷新处理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this); } else { logger.debug("Refreshing " + getDisplayName()); } } initPropertySources(); getEnvironment().validateRequiredProperties(); if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } this.earlyApplicationEvents = new LinkedHashSet<>(); }
|