一樣,咱們仍是以 AnnotationConfigApplicationContext 做爲切入點,開始對總體功能進行分析。java
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }
進入this();spring
public AnnotationConfigApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
先執行父類的初始化方法,建立IOC容器bootstrap
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
2.進入AnnotatedBeanDefinitionReader方法執行初始化方法建立BeanDefinition讀取器app
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
AnnotationConfigUtils獲取全部BeanPostProcessor的Bean,把下面6個對象注入到IOC容器中了編輯器
這裏用到了CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME 、AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME 等幾個常量ide
常量 | 對應的BeanPostProcessor | 對應的註解 |
CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME | ConfigurationClassPostProcessor | @Configuration |
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME | AutowiredAnnotationBeanPostProcessor | @AutoWired |
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME | RequiredAnnotationBeanPostProcessor | @Required |
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME | CommonAnnotationBeanPostProcessor | @javax.annotation.PostConstruct、@javax.annotation.PreDestroy |
等等,還有幾個,就不列了。函數
3.進入ClassPathBeanDefinitionScanner方法建立classPath下掃描器工具
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (useDefaultFilters) { registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(resourceLoader); }
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
}
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null);
}
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);//建立BeanDefinition對象 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { //處理 @Condition註解 return; } abd.setInstanceSupplier(instanceSupplier); //設置對象是單例模式仍是多例模式,默認單例 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); //獲取BeanName,設置的化就採用默認值,不然類名第一個字母小寫 String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); //處理Lazy,primary等註解 ..... BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//判斷對象是否須要代理,不須要直接返回,須要的化,從新建立BeanDefinition加入代理的信息 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); //註冊配置類到IOC容器 }
進入 refresh()方法,能夠說refresh函數中包括了幾乎ApplicationContext中提供的所有功能,並且此函數中邏輯很是清晰明瞭。post
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh();//準備刷新上下文環境 // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//初始化BeanFacgtory // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory);//初始化BeanFactory進行各類功能填充 try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory);//子類覆蓋方法作額外的處理 // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory);//激活各類BeanFactory處理器 // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory);//註冊攔截Bean建立的Bean處理器,這裏只是註冊,真正的調用是在getBean的時候 // Initialize message source for this context. initMessageSource();//爲上下文初始化Message源,集不一樣語言的消息體,國際化處理 // Initialize event multicaster for this context. initApplicationEventMulticaster();//初始化應用消息廣播器,並放入applicationEventMulticaster bean中 // Initialize other special beans in specific context subclasses. onRefresh();//留給子類來初始化其它的Bean // Check for listener beans and register them. registerListeners();//在全部註冊的Bean中查找Listener bean,註冊到消息廣播器中 // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory);//初始化剩下的單實例(非惰性) // Last step: publish corresponding event. finishRefresh();//完成刷新過程,通知生命週期處理器 LifecycleProcessor刷新過程,同時發出 ContextRefreshedEvent 通知別人 } catch (BeansException ex) { // Destroy already created singletons to avoid dangling resources. destroyBeans();//銷燬Bean // Reset 'active' flag. cancelRefresh(ex);//更改活躍狀態 // Propagate exception to caller. throw ex; } } }
prepareRefresh();函數主要做用是對系統屬性及環境變量的初始化及驗證測試
/** * Prepare this context for refreshing, setting its startup date and * active flag as well as performing any initialization of property sources. */ protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // Initialize any placeholder property sources in the context environment initPropertySources();//留給子類覆蓋 // Validate that all properties marked as required are resolvable // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties();//驗證須要的屬性文件是否都已經放入環境中去了 // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<>(); }
initPropertySources是空的,沒有任何邏輯處理, 而getEnvironment().validateRequiredProperties()也是由於沒有須要驗證的屬性而沒有作任何處理,然而這兩個方法做用仍是很大的。那麼該怎麼用呢?
1.initPropertySources正符合Spring的開放式結構設計,給用戶最大的擴展Spring的能力。
2.validateRequiredProperties則是對屬性進行驗證,那麼如何驗證呢?咱們舉個例子來講明下:
public class MyAnnotationConfigApplication extends AnnotationConfigApplicationContext { public MyAnnotationConfigApplication(Class<?>... annotatedClasses){ super(annotatedClasses); } @Override protected void initPropertySources(){ //添加驗證要求 getEnvironment().setRequiredProperties("VAR"); } }
咱們自定義了繼承自AnnotationConfigApplicationContext的MyAnnotationConfigApplication,並重寫了initPropertySources方法,在方法中添加了咱們的個性化需求,那麼在驗證的時候也就是程序走到
validateRequiredProperties()代碼的時候,咱們還須要替換掉原有的AnnotationConfigApplicationContext爲咱們自定義的MyAnnotationConfigApplication。
public class Test002 {
public static void main(String[] args) {
ApplicationContext context = new MyAnnotationConfigApplication(MyConfig.class);
Object payEntity = context.getBean("payEntity");
System.out.println(payEntity);
}
}
若是系統並無檢測到對應的VAR環境變量,那麼就會拋出異常:
obtainFreshBeanFactory()方法的做用是:通過這個方法,ApplicationContext就已經擁有了BeanFactory的所有功能。
/** * Tell the subclass to refresh the internal bean factory. * @return the fresh BeanFactory instance * @see #refreshBeanFactory() * @see #getBeanFactory() */ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //初始化BeanFactory refreshBeanFactory(); //返回當前實體的BeanFactory屬性 ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
方法中將核心實現委託給了refreshBeanFactory:
/** * This implementation performs an actual refresh of this context's underlying * bean factory, shutting down the previous bean factory (if any) and * initializing a fresh bean factory for the next phase of the context's lifecycle. */ @Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory();//建立DefaultListableBeanFactory beanFactory.setSerializationId(getId());//序列化id customizeBeanFactory(beanFactory);//定製BeanFactory,設置相關屬性,是否容許循環依賴,是否容許覆蓋 loadBeanDefinitions(beanFactory);//加載BeanDefinition synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { //若是屬性不爲空,則設置給beanFactory對象相應屬性,此屬性的含義是:是否容許覆蓋同名稱的不一樣定義的對象 if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } //若是屬性不爲空,設置給beanFactory對象相應的屬性,這塊屬性的含義是:是否容許Bean之間存在循環依賴 if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); } }
對於容許覆蓋和容許循環依賴的設置這裏只是進行了非空判斷,若是不爲空的化要進行設置,可是這裏沒有設置,因此仍是那個套路,使用子類覆蓋方法。
public class MyAnnotationConfigApplication extends AnnotationConfigApplicationContext { public MyAnnotationConfigApplication(Class<?>... annotatedClasses){ super(annotatedClasses); } protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory){ super.setAllowBeanDefinitionOverriding(false);//是否容許覆蓋同名稱的不一樣定義的對象 super.setAllowCircularReferences(false);//是否容許Bean之間存在循環依賴 } }
/** * Loads the bean definitions via an XmlBeanDefinitionReader. * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader * @see #initBeanDefinitionReader * @see #loadBeanDefinitions */ @Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // Create a new XmlBeanDefinitionReader for the given BeanFactory. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);//爲指定的beanFactory建立XmlBeanDefinitionReader // Configure the bean definition reader with this context's // resource loading environment. beanDefinitionReader.setEnvironment(this.getEnvironment());//對beanDefinitionReader進行環境變量的設置 beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, // then proceed with actually loading the bean definitions. initBeanDefinitionReader(beanDefinitionReader);//進行設置能夠覆蓋 loadBeanDefinitions(beanDefinitionReader); }
在初始化了DefaultListableBeanFactory和XmlBeanDefinitionReader後就能夠進行配置文件的讀取了
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { Resource[] configResources = getConfigResources(); if (configResources != null) { reader.loadBeanDefinitions(configResources); } String[] configLocations = getConfigLocations(); if (configLocations != null) { reader.loadBeanDefinitions(configLocations); } }
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
for (Resource resource : resources) {
counter += loadBeanDefinitions(resource);
}
return counter;
}
通過此步驟,類型DefaultListableBeanFactory的變量beanFactory已經包含了全部已經解析好的配置
進入函數prepareBeanFactory前,Spring已經完成了對配置的解析,而ApplicationContext在功能上的擴展也由此展開。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader());//設置BeanFactory的classLoader爲當前context的classLoader beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));//設置beanFactory的表達式語言處理器,默承認以使用#{bean.xx}的形式來調用相關的屬性值。 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));//爲BeanFactory增長了一個默認的propertyEditor,這個主要是對bean的屬性等設置管理的一個工具 // Configure the bean factory with context callbacks. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));//添加BeanPostProcessor //設置了幾個忽略自定裝配的接口 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); //設置了幾個自定裝配的規則 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. 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())); } // 添加了默認的系統環境bean 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()); } }
上面函數中主要進行了幾個方面的擴展
- 增長了對SpEL語言的支持
- 增長對屬性編輯器的支持
- 增長了對一些內置類,好比實現了Aware接口的類信息注入
- 設置了依賴功能可忽略接口
- 註冊一些固定依賴的屬性
- 增長了AspectJ的支持,後面再去分析
- 將相關環境變量及屬性註冊以單例模式註冊
上面可擴展功能不少,我就不一一介紹了,下面咱們來挑幾個咱們感興趣的函數來分析下:
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)),其主要目的就是註冊個BeanPostProcessor,而真正的邏輯仍是在ApplicationContextAwareProcessor中
ApplicationContextAwareProcessor實現了BeanPostProcessor接口,咱們回顧下以前講解的內容,在Bean實例化的時候,也就是Spring激活Bean的init-method方法先後,
會調用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法。因此咱們也就去看看ApplicationContextAwareProcessor對這兩個方法的實現。
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
對於後置處理器BeanPostProcessor的後置處理方法中並無作任何邏輯處理,那麼咱們轉向後置處理器的前置處理
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { AccessControlContext acc = null; if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareInterfaces(bean); return null; }, acc); } else { invokeAwareInterfaces(bean); } return bean; }
private void invokeAwareInterfaces(Object bean) { if (bean instanceof Aware) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); } } }
postProcessBeforeInitialization方法中調用了invokeAwareInterfaces。從invokeAwareInterfaces方法中,咱們或許已經差很少知道了Spring的用意,實現了這些Aware接口的Bean在被初始化後,能夠取到一些對於的資源。
示例:
@Component public class MyApplicationContext implements ApplicationContextAware { /** * spring底層中爲何可以實現ApplicationContextAware接口 就可以拿到ApplicationContext * @param applicationContext * @throws BeansException */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("applicationContext:>>>>"+applicationContext); } }
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()));
}
}
咱們自定義MyInstantiationAwareBeanPostProcessor實現BeanPostProcessor 接口
@Component
public class MyInstantiationAwareBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization....");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization....");
return null;
}
}
@Import(MyInstantiationAwareBeanPostProcessor.class)
結果輸出:每次初始化一個Bean就會在以前和以後處理一些自定義邏輯
postProcessBeforeInitialization....
4.bean init方法執行..
postProcessAfterInitialization....
/** * Initialize the ApplicationEventMulticaster. * Uses SimpleApplicationEventMulticaster if none defined in the context. * @see org.springframework.context.event.SimpleApplicationEventMulticaster */ protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isDebugEnabled()) { logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isDebugEnabled()) { logger.debug("Unable to locate ApplicationEventMulticaster with name '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this.applicationEventMulticaster + "]"); } } }
進入SimpleApplicationEventMulticaster找到這段代碼:
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) { Executor executor = getTaskExecutor(); if (executor != null) { executor.execute(() -> invokeListener(listener, event)); } else { invokeListener(listener, event); } } }
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) { ErrorHandler errorHandler = getErrorHandler(); if (errorHandler != null) { try { doInvokeListener(listener, event); } catch (Throwable err) { errorHandler.handleError(err); } } else { doInvokeListener(listener, event); } }
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
....
listener.onApplicationEvent(event);
}
能夠推斷,當產生Spring事件的時候會默認使用SimpleApplicationEventMulticaster的multicastEvent來廣播事件,遍歷全部監聽器,並使用監聽器中的onApplicationEvent方法來進行監聽事件的處理。
而對於每一個監聽器來講其實均可以獲取到產生的事件,可是是否進行處理則由事件監聽器來決定。
進入registerListeners函數,開始註冊監聽器:
protected void registerListeners() { for (ApplicationListener<?> listener : getApplicationListeners()) {//硬編碼方式註冊的監聽器處理 getApplicationEventMulticaster().addApplicationListener(listener); } String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);//配置文件註冊的監聽器處理 for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
Application下抽象子類ApplicationContextEvent的下面有4個已經實現好的事件
- ContextClosedEvent(容器關閉時)
- ContextRefreshedEvent(容器刷新時)
- ContextStartedEvent(容器啓動時候)
- ContextStoppedEvent(容器中止的時候)
一樣,這四個事件都繼承了ApplicationEvent,若是咱們想自定義事件,也能夠經過繼承ApplicationEvent來實現
使用示例:
1.定義監聽事件
public class TestEvent extends ApplicationEvent {
private String msg;
public TestEvent(Object source){
super(source);
}
public TestEvent(Object source,String msg){
super(source);
this.msg=msg;
}
public void print(){
System.out.println(msg);
}
}
2.定義監聽器
public class TestListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEvent event) { if (event instanceof TestEvent){ TestEvent testEvent= (TestEvent)event; testEvent.print(); } } }
注入容器
@Import(TestListener.class)
測試:
public class Test001 { public static void main(String[] args) { /** * IOC容器初始化單例對象都是循環遍歷調用getBean方法 */ AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class); TestEvent testEvent = new TestEvent("hello", "hello word"); applicationContext.publishEvent(testEvent); } }
輸出結果:
咱們在補充一個註解形式的例子:
public class TestEvent extends ApplicationEvent {
private String msg;
public TestEvent(Object source){
super(source);
}
public TestEvent(Object source,String msg){
super(source);
this.msg=msg;
}
public void print(){
System.out.println("註冊監聽器..,TestEvent....");
}
}
@Component
public class MyAnnotationListener {
@EventListener
public String listener1(TestEvent event) {
if (event instanceof TestEvent){
TestEvent testEvent=event;
testEvent.print();
}
return "xd";
}
}
@Import(MyAnnotationListener.class)
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class); MyAnnotationListener myAnnotationListener = new MyAnnotationListener(); applicationContext.publishEvent(myAnnotationListener.listener1(new TestEvent("jj")));
輸出:
進入finishBeanFactoryInitialization函數初始化全部非懶加載Bean
/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService(//定義轉換器從String轉爲Date的方式,能夠本身擴展,我就很少說了 beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration();//凍結全部Bean的定義,說明註冊的Bean定義將不被修改或處理。 // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons();//初始化剩下的單實例(非惰性) }
@Override public void freezeConfiguration() { this.configurationFrozen = true; this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
ApplicationContext實現的默認行爲就是在啓動時將全部單例bean提早進行實例化。提早實例化的好處是,在配置中任何錯誤就會當即被發現Z(不然的化,一旦出錯,排除bug至關困難)。
public void preInstantiateSingletons() throws BeansException { if (this.logger.isDebugEnabled()) { this.logger.debug("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); 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()); } if (isEagerInit) { getBean(beanName); } } else { getBean(beanName); } } }
在Spring中還提供了Lifecycle接口,Lifecycle接口中包含start/stop方法,實現此接口後Spring會保證在啓動的時候調用其start方法開始生命週期,而且在spring關閉的時候調用stop方法來結束生命週期,
一般用來配置後臺程序,在啓動後一直運行(such as MQ進行輪詢等)。
/** * Finish the refresh of this context, invoking the LifecycleProcessor's * onRefresh() method and publishing the * {@link org.springframework.context.event.ContextRefreshedEvent}. */ protected void finishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). clearResourceCaches(); // Initialize lifecycle processor for this context. initLifecycleProcessor();//當ApplicationContext啓動或者中止時,會經過LifecycleProcessor來與全部聲明的bean的週期作狀態更新,而在LifecycleProcessor使用前須要初始化 // Propagate refresh to lifecycle processor first. getLifecycleProcessor().onRefresh();//啓動全部實現了Lifecycle接口的bean // Publish the final event. publishEvent(new ContextRefreshedEvent(this));//當完成ApplicationContext初始化的時候,要經過Spring中的事件發佈機制來發出ContextRefreshedEvent監聽事件,以保證對應的監聽器能夠作進一步的邏輯處理 // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
到這裏,咱們就談完了!!!
參考書籍:Spring源碼深度解析
版權全部:https://my.oschina.net/u/3995125,禁止轉載