<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
通過aware介面可以獲取Spring容器相關資訊,但這樣會與Spring容器耦合。
執行順序從上到下。
類名 | 作用 |
---|---|
BeanNameAware | 獲得容器中bean名稱 |
BeanClassLoaderAware | 獲得類載入器 |
BeanFactoryAware | 獲得bean建立工廠 |
EnvironmentAware | 獲得環境變數 |
EmbeddedValueResolverAware | 獲取spring容器載入的properties檔案屬性值 |
ResourceLoaderAware | 獲得資源載入器 |
ApplicationEventPublisherAware | 獲得應用事件釋出器 |
MessageSourceAware | 獲得文字資訊 |
ApplicationContextAware | 獲得當前應用上下文 |
/** * 獲取spring注入物件方法 */ @Component("springUtil") public final class SpringUtil implements ApplicationContextAware { /** * 應用上下文 */ private static ApplicationContext applicationContext; /** * public方法可能被呼叫,導致執行緒不安全。這樣寫也是為了通過sonar檢測 * @param applicationContext 通過aware設定上下文 */ @Override public void setApplicationContext(@NonNull ApplicationContext applicationContext) { synchronized (SpringUtil.class) { if (null == SpringUtil.applicationContext) { SpringUtil.applicationContext = applicationContext; } } } /** * 獲取注入物件 * * @param name 物件名稱 * @return 指定注入物件 */ public static Object getBean(String name) { return getApplicationContext().getBean(name); } private static ApplicationContext getApplicationContext() { return applicationContext; } /** * 獲取注入物件 * * @param clazz 物件型別 * @param <T> 泛型 * @return 指定注入物件 */ public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); } /** * 獲取注入物件 * * @param name 物件名稱 * @param clazz 物件型別 * @param <T> 泛型 * @return 指定注入物件 */ public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); } }
先定義一個繼承Aware的介面,然後註冊一個實現BeanPostProcessor介面的Bean,在postProcessBeforeInitialization中處理Aware介面的邏輯。
舉一個例子。獲取呼叫自定義Aware介面方法的時間。
public interface TimeAware extends Aware { void setTriggerTime(Date date); }
@Component public class AwarePostProcessor implements BeanPostProcessor { private final ConfigurableApplicationContext applicationContext; /** * 可寫可不寫,這個構造是為了獲取applicationContext */ public AwarePostProcessor(ConfigurableApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Aware) { if (bean instanceof TimeAware) { // 實現自定義Aware介面的邏輯,設定呼叫的時間 ((TimeAware)bean).setTriggerTime(new Date()); } } return bean; } }
@Import(AwarePostProcessor.class) public class Test implements TimeAware { Date date; @Override public void setTriggerTime(Date date) { this.date = date; } public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(Test.class); Test bean = context.getBean(Test.class); System.out.println(bean.date); } }
結果:
1.先執行實現了下面三個aware介面的方法
2.呼叫初始化方法
3.執行實現剩下aware介面的方法
AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { /** * 呼叫Bean實現的Aware介面的方法,主要包括下面三個介面 * BeanNameAware ----> setBeanName() * BeanClassLoaderAware ----> setBeanClassLoader() * BeanFactoryAware ----> setBeanFactory() */ invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { /** 呼叫Bean物件的postProcessBeforeInitialization方法,此處會執行標註@PostConstruct註解的方法 */ // 此處會呼叫ApplicationContextAwareProcessor執行其他的aware方法. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { /** * 執行Bean的初始化方法: * * 1.先判斷Bean是否實現了InitializingBean介面,如果實現了InitializingBean介面,則呼叫Bean物件的afterPropertiesSet方法; * 2.然後判斷Bean是否有指定init-method方法,如果指定了init-method方法,則呼叫bean物件的init-method指定的方法. */ 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()) { /** * 呼叫Bean物件的postProcessAfterInitialization方法 * * 如果需要建立代理,在該步驟中執行postProcessAfterInitialization方法的時候會去建立代理 * 呼叫AbstractAutoProxyCreator類的postProcessAfterInitialization方法,然後呼叫wrapIfNecessary方法去建立代理. * * * 另外還有一些Aware介面,也會在該步驟中執行,例如:ApplicationContextAwareProcessor後置處理器,對應的setApplicationContext方法會被執行. */ wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
呼叫initializeBean =>invokeAwareMethods方法將前三個aware方法呼叫
AbstractAutowireCapableBeanFactory#invokeAwareMethods
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); } } }
呼叫initializeBean =>applyBeanPostProcessorsBeforeInitialization=>BeanPostProcessor.postProcessBeforeInitialization
進入ApplicationContextAwareProcessor#postProcessBeforeInitialization=>invokeAwareInterfaces
private void invokeAwareInterfaces(Object bean) { 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); } }
因此可以自定義aware介面,並且註冊一個實現BeanPostProcessor的postProcessBeforeInitialization方法的Bean,處理呼叫aware方法時的處理邏輯。
相關文章
<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