日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

茅塞顿开:Spring Aware原理解析

發布時間:2024/4/13 javascript 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 茅塞顿开:Spring Aware原理解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題

為什么被Spring管理的類。只要實現了Aware接口。Spring就會自動把對應的對象注入進來。這個bean如果想要使用直接使用就可以了。如下: Spring會自動把ApplicationContext注入到AwareTest這個bean里面。

public class AwareTest implements ApplicationContextAware {public ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}public void checkAware(){if(applicationContext != null){System.out.println("ApplicationContext inject success");}} }

源碼解析:

1. 我們都知道在AbstractApplicationContext里面真正的啟動ApplicationContext的函數是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();// Prepare the bean factory for use in this context.prepareBeanFactory(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);// Register bean processors that intercept bean creation.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();}}}

2. 可以看到有一個prepareBeanFactory的方法,我們再往里面看一下這個方法里面究竟有什么。可以發現給BeanFactory添加了一個BeanPostProcessor。名字是ApplicationContextAwareProcessor?

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.beanFactory.setBeanClassLoader(getClassLoader());beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(EnvironmentAware.class);... 多余的代碼不貼出來了}

3. BeanPostProcessor這個接口我們都很熟悉了。我們看一下這個里面PostProcessBeforeInitialization()函數。傳入bean和beanName。最后是調用了invokeAwareInterfaces(bean)這個函數。如果bean 是aware類的子類。那么就調用bean的set方法將ApplicationContext塞到bean里面。然后業務代碼在需要使用ApplicationContext的時候就可以直接使用了。因為已經被set進來了。
?

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);}}}

4. 我們再來看一下。Spring是什么時候調用了BeanPostProcessor的postProcessBeforeInitialization函數的。在AbstractAutowireCapableBeanFactory的initializeBean方法里面 , 在調用InvokeInitMethods的方法之前。先執行了applyBeanPost

ProcessorBeforeInitialization的方法。這個方法里面就是將所有的BeanPostProcessor的的postProcessBeforeInitialization()都執行一遍。包括之前創建的ApplicationContextAwareProcessor。于是ApplicationContextAwareProcessor這個時刻就將ApplicationContext注入到我們的Bean里面了。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}

上面是跟著源碼走了一遍。我看完之后的理解就是。Spring在整個設計上對于這種松耦合和可插拔真是做了非常多的工作。可以說Spring 本身的ioc的代碼并不復雜。大量的代碼工作都是為了方便開發者自己去拓展Spring的邊界。讓開發者可以更好的去控制和管理bean這個對象。Spring的代碼建議多讀幾遍。雖然每一遍讀起來都很痛苦。但是每一次讀都會有新的感受。
?

總結

以上是生活随笔為你收集整理的茅塞顿开:Spring Aware原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。