<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前一篇講到了BeanPostProcessor的相關知識,我們知道BeanPostProcessor是對整個容器中的Bean做前置和後置增強處理。這樣的實現方式限制了開發者只能按照Spring提供的模板,對Bean做前置和後置的增強,這樣雖然已經很靈活了,但是如果開發者想要對Spring中的Bean做更復雜的操作或者開發者想要使用Spring中的BeanFactory、ClassLoader時,這樣的方式明顯就不夠方便了,因此Spring也考慮到了這樣的情況,就提供了另外的方式提升Spring的擴充套件性和靈活性,這種方式就是Aware。
單純說Aware可能不熟悉,但是如果說BeanNameAware、BeanFactoryAware那麼是不是就知道這個Aware到底是何方神聖了。
接下來就說一下Spring提供給開發者Aware的這個功能。
Spring中Aware的原始碼如下:
public interface Aware { }
從原始碼中可以看到Aware就是一個簡單的介面,該介面是一個無實現的介面,一般看到這種介面可以都是作為最頂級的父類別介面使用的,使用時一般都是instanceof判斷是否是頂級介面型別。
在Spring中Aware有幾個繼承介面,分別是:
首先是BeanClassLoaderAware介面,從字面意思翻譯就可以大概知道這是一個關於Bean的類載入器的介面,因此該介面的功能就聚焦在類載入器上。
BeanClassLoaderAware原始碼如下:
public interface BeanClassLoaderAware extends Aware { //set方法,賦值ClassLoader方法 void setBeanClassLoader(ClassLoader classLoader); }
從原始碼可以看到該介面只提供了一個setBeanClassLoader方法,該方法就是簡單的設定Bean的類載入器的方法,所以從這個方法中就可以知道BeanClassLoaderAware就單純提供了一個賦值ClassLoader的方法,這裡的介面並不會指定ClassLoader的接收方,因此接收方需要在實現該介面的實現類中指定,然後將ClassLoader賦值給實現類中的具體常數。
BeanFactoryAware介面,看到這個就立馬想到Spring中的BeanFactory,BeanFactory在Spring中是作為Bean的工廠,那麼該介面一定是與BeanFactory相關的介面。
BeanFactoryAware原始碼如下:
public interface BeanFactoryAware extends Aware { void setBeanFactory(BeanFactory beanFactory) throws BeansException; }
從原始碼中可以看到BeanFactoryAware跟BeanClassLoaderAware相似都只提供了一個set方法,該介面中只定義了setBeanFactory一個方法。
該介面中的方法 功能跟BeanClassLoaderAware功能相同,都是賦值,但是該介面賦值的是BeanFactory。
原始碼如下:
public interface BeanNameAware extends Aware { void setBeanName(String name); }
該介面功能同上。(說實話實際開發中沒用到過這個,只用過前兩個,所以我也沒搞懂該類到底可以幹啥)。
該介面則是一個特別的介面了,因為該介面跟前三個繼承Aware的介面不同,ApplicationContextAware並不是spring-bean中提供的介面,而是在spring-context中提供的介面,該介面是從spring-context包中提供的介面,該介面的作用也是跟前三個類似,並且大部分開發者用的最多的也是這個。
原始碼如下:
public interface ApplicationContextAware extends Aware { void setApplicationContext(ApplicationContext applicationContext) throws BeansException; }
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver { @Nullable String getId(); String getApplicationName(); String getDisplayName(); long getStartupDate(); @Nullable ApplicationContext getParent(); AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException; }
原始碼中也是簡單的賦值操作,但是賦值的物件是ApplicationContext物件,對於這個物件使用Spring的一定不陌生。
可以這樣說:ApplicationContext給了開發者最多的許可權用於操作Bean。
從ApplicationContext原始碼中也可以看到該介面繼承了ListableBeanFactory、HierarchicalBeanFactory、ApplicationEventPublisher等其它介面,這樣就將更多的Bean的許可權通過ApplicationContext下放給開發者!(又是被Spring的高靈活性折服的時刻)。
@Component public class MySpringAware implements BeanFactoryAware, BeanClassLoaderAware, ApplicationContextAware, BeanNameAware { private ApplicationContext applicationContext; private ListableBeanFactory beanFactory; private ClassLoader classLoader; private String beanName; /** * 獲取某個介面下的所有實現類 * * @param filter */ public void registryFilter(FilterProcessor filter) { Map<String, MyFilter> beans = beanFactory.getBeansOfType(MyFilter.class); beans.values().stream().sorted(AnnotationAwareOrderComparator.INSTANCE).forEach(filter::register); } /** * 獲取環境設定 * * @return */ public Environment getApplicationData() { return applicationContext.getEnvironment(); } public ApplicationContext getApplicationContext() { return applicationContext; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public void setBeanClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = (ListableBeanFactory) beanFactory; } @Override public void setBeanName(String s) { this.beanName = s; } }
@Component public class FilterProcessor { private final List<MyFilter> filterList = new ArrayList(); public void register(MyFilter filter) { this.filterList.add(filter); } public List<MyFilter> getFilterList() { return filterList; } }
public interface MyFilter { void doFilter(); }
@Component @Order(1) public class MyDemoFilter extends FilterProcessor implements MyFilter{ @Override public void doFilter() { System.out.println("執行第一個過濾器MyDemoFilter"); } } @Component @Order(2) public class MyDemoFilter2 extends FilterProcessor implements MyFilter{ @Override public void doFilter() { System.out.println("執行第二個過濾器MyDemoFilter2"); } }
執行結果:
以上的例子中通過MySpringAware實現了前文中說到的幾個Aware,分別使用了其中的BeanFactory和ApplicationContext。這樣在MySpringAware中就可以使用我們定義的常數接收Spring容器中的BeanFactory、ClassLoader、ApplicationContext等功能。
從以上的例子中可以看到,Aware為開發者提供了插樁式的介面,開發者只要實現該介面就可以獲得Spring容器的某些管理權。
比如BeanClassLoaderAware是獲得對Bean的類載入器的管理權。
BeanFactoryAware是活的對Bean工廠的管理權。
這樣插樁式的擴充套件可以保證開發者在使用時可以獲得Spring中某些功能的管理權,方便開發者對Spring的理解和使用,不需要複雜的實現就可以獲得Spring內部的管理。
前面說完了Aware的介紹、類別和作用,最後來說實現Aware相關介面的實現類在Spring中是如何被呼叫的。
實現Aware相關介面的實現類被呼叫的方式與前面講的BeanPostProcessor有一定區別。
區別如下:
BeanPostProcessor的呼叫:
Aware的呼叫:
原始碼如下:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { //初始化Bean的方法 protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { //呼叫Bean的Aware重寫介面 invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { //呼叫Bean的Aware重寫介面 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //呼叫BeanPostProcessor前置介面 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //呼叫Bean的初始化函數 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()) { //呼叫BeanPostProcessor後置介面 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } //呼叫Aware的實現 private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } } }
區別梳理如下:
以AbstractAutowireCapableBeanFactory為主線梳理呼叫Aware介面的鏈路如下:
對於ApplicationContextAware的呼叫鏈路梳理如下:
根據以上的鏈路可以很清晰的看到ApplicationContextAware的呼叫實現。
以上就是Spring Aware原始碼設計範例解析的詳細內容,更多關於Spring Aware原始碼設計的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45