做者:小傅哥
博客:https://bugstack.cnhtml
沉澱、分享、成長,讓本身和他人都能有所收穫!😄
同事寫的代碼,我竟絲毫看不懂!
java
大佬的代碼,就像 「賴蛤蟆泡青蛙,張的醜玩的花」:一個類實現了多個接口、繼承的類又繼承了其餘類、接口還能夠和接口繼承、實現接口的抽象類再由類實現抽象類方法、類A繼承的類B實現了類A實現的接口C,等等。程序員
看上去複雜又難懂
的代碼,卻又能一次次知足需求的高效迭代和順利擴展,而像螺絲釘同樣搬磚的你,只是在大佬
寫的代碼裏,完成某個接口下的一小塊功能,甚至寫完了也不知道怎麼就被調用運行了,整個過程像看 Spring 源碼同樣神奇,跳來跳去的摸不着頭緒!spring
其實這主要是由於你的代碼是否運用了設計模式,固然設計模式也沒那麼神奇,就像大家兩家都是120平米的房子,他家有三室兩廳一廚一衛,南北通透,全陽採光。但你家就不同了,你家是鍋碗瓢盆、衛浴馬桶、沙發茶几還有那1.8的雙人牀,在120平米的房子裏敞開了放,沒有動靜隔離,也沒有乾溼分離,純自由發揮。因此你的代碼看上去就亂的很!設計模式
目前已實現的 Spring 框架,在 Bean 操做上能提供出的能力,包括:Bean 對象的定義和註冊,以及在操做 Bean 對象過程當中執行的,BeanFactoryPostProcessor、BeanPostProcessor、InitializingBean、DisposableBean,以及在 XML 新增的一些配置處理,讓咱們能夠 Bean 對象有更強的操做性。微信
那麼,若是咱們想得到 Spring 框架提供的 BeanFactory、ApplicationContext、BeanClassLoader等這些能力作一些擴展框架的使用時該怎麼操做呢。因此咱們本章節但願在 Spring 框架中提供一種能感知容器操做的接口,若是誰實現了這樣的一個接口,就能夠獲取接口入參中的各種能力。多線程
若是說我但願拿到 Spring 框架中一些提供的資源,那麼首先須要考慮以一個什麼方式去獲取,以後你定義出來的獲取方式,在 Spring 框架中該怎麼去承接,實現了這兩項內容,就能夠擴展出你須要的一些屬於 Spring 框架自己的能力了。架構
在關於 Bean 對象實例化階段咱們操做過一些額外定義、屬性、初始化和銷燬的操做,其實咱們若是像獲取 Spring 一些如 BeanFactory、ApplicationContext 時,也能夠經過此類方式進行實現。那麼咱們須要定義一個標記性的接口,這個接口不須要有方法,它只起到標記做用就能夠,而具體的功能由繼承此接口的其餘功能性接口定義具體方法,最終這個接口就能夠經過 instanceof
進行判斷和調用了。總體設計結構以下圖:app
ApplicationContextAwareProcessor
操做,最後由 AbstractAutowireCapableBeanFactory 建立 createBean 時處理相應的調用操做。關於 applyBeanPostProcessorsBeforeInitialization 已經在前面章節中實現過,若是忘記能夠往前翻翻small-spring-step-08 └── src ├── main │ └── java │ └── cn.bugstack.springframework │ ├── beans │ │ ├── factory │ │ │ ├── factory │ │ │ │ ├── AutowireCapableBeanFactory.java │ │ │ │ ├── BeanDefinition.java │ │ │ │ ├── BeanFactoryPostProcessor.java │ │ │ │ ├── BeanPostProcessor.java │ │ │ │ ├── BeanReference.java │ │ │ │ ├── ConfigurableBeanFactory.java │ │ │ │ └── SingletonBeanRegistry.java │ │ │ ├── support │ │ │ │ ├── AbstractAutowireCapableBeanFactory.java │ │ │ │ ├── AbstractBeanDefinitionReader.java │ │ │ │ ├── AbstractBeanFactory.java │ │ │ │ ├── BeanDefinitionReader.java │ │ │ │ ├── BeanDefinitionRegistry.java │ │ │ │ ├── CglibSubclassingInstantiationStrategy.java │ │ │ │ ├── DefaultListableBeanFactory.java │ │ │ │ ├── DefaultSingletonBeanRegistry.java │ │ │ │ ├── DisposableBeanAdapter.java │ │ │ │ ├── InstantiationStrategy.java │ │ │ │ └── SimpleInstantiationStrategy.java │ │ │ ├── support │ │ │ │ └── XmlBeanDefinitionReader.java │ │ │ ├── Aware.java │ │ │ ├── BeanClassLoaderAware.java │ │ │ ├── BeanFactory.java │ │ │ ├── BeanFactoryAware.java │ │ │ ├── BeanNameAware.java │ │ │ ├── ConfigurableListableBeanFactory.java │ │ │ ├── DisposableBean.java │ │ │ ├── HierarchicalBeanFactory.java │ │ │ ├── InitializingBean.java │ │ │ └── ListableBeanFactory.java │ │ ├── BeansException.java │ │ ├── PropertyValue.java │ │ └── PropertyValues.java │ ├── context │ │ ├── support │ │ │ ├── AbstractApplicationContext.java │ │ │ ├── AbstractRefreshableApplicationContext.java │ │ │ ├── AbstractXmlApplicationContext.java │ │ │ ├── ApplicationContextAwareProcessor.java │ │ │ └── ClassPathXmlApplicationContext.java │ │ ├── ApplicationContext.java │ │ ├── ApplicationContextAware.java │ │ └── ConfigurableApplicationContext.java │ ├── core.io │ │ ├── ClassPathResource.java │ │ ├── DefaultResourceLoader.java │ │ ├── FileSystemResource.java │ │ ├── Resource.java │ │ ├── ResourceLoader.java │ │ └── UrlResource.java │ └── utils │ └── ClassUtils.java └── test └── java └── cn.bugstack.springframework.test ├── bean │ ├── UserDao.java │ └── UserService.java └── ApiTest.java
工程源碼:公衆號「bugstack蟲洞棧」,回覆:Spring 專欄,獲取完整源碼
框架
Spring 感知接口的設計和實現類關係,如圖 9-2
addBeanPostProcessor
,再由 createBean 統一調用 applyBeanPostProcessorsBeforeInitialization 時進行操做。cn.bugstack.springframework.beans.factory.Aware
/** * Marker superinterface indicating that a bean is eligible to be * notified by the Spring container of a particular framework object * through a callback-style method. Actual method signature is * determined by individual subinterfaces, but should typically * consist of just one void-returning method that accepts a single * argument. * * 標記類接口,實現該接口能夠被Spring容器感知 * */ public interface Aware { }
cn.bugstack.springframework.beans.factory.BeanFactoryAware
public interface BeanFactoryAware extends Aware { void setBeanFactory(BeanFactory beanFactory) throws BeansException; }
cn.bugstack.springframework.beans.factory.BeanClassLoaderAware
public interface BeanClassLoaderAware extends Aware{ void setBeanClassLoader(ClassLoader classLoader); }
cn.bugstack.springframework.beans.factory.BeanNameAware
public interface BeanNameAware extends Aware { void setBeanName(String name); }
cn.bugstack.springframework.context.ApplicationContextAware
public interface ApplicationContextAware extends Aware { void setApplicationContext(ApplicationContext applicationContext) throws BeansException; }
cn.bugstack.springframework.context.support.ApplicationContextAwareProcessor
public class ApplicationContextAwareProcessor implements BeanPostProcessor { private final ApplicationContext applicationContext; public ApplicationContextAwareProcessor(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof ApplicationContextAware){ ((ApplicationContextAware) bean).setApplicationContext(applicationContext); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
cn.bugstack.springframework.context.support.AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { @Override public void refresh() throws BeansException { // 1. 建立 BeanFactory,並加載 BeanDefinition refreshBeanFactory(); // 2. 獲取 BeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 3. 添加 ApplicationContextAwareProcessor,讓繼承自 ApplicationContextAware 的 Bean 對象都能感知所屬的 ApplicationContext beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 4. 在 Bean 實例化以前,執行 BeanFactoryPostProcessor (Invoke factory processors registered as beans in the context.) invokeBeanFactoryPostProcessors(beanFactory); // 5. BeanPostProcessor 須要提早於其餘 Bean 對象實例化以前執行註冊操做 registerBeanPostProcessors(beanFactory); // 6. 提早實例化單例Bean對象 beanFactory.preInstantiateSingletons(); } // ... }
cn.bugstack.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { bean = createBeanInstance(beanDefinition, beanName, args); // 給 Bean 填充屬性 applyPropertyValues(beanName, bean, beanDefinition); // 執行 Bean 的初始化方法和 BeanPostProcessor 的前置和後置處理方法 bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } // 註冊實現了 DisposableBean 接口的 Bean 對象 registerDisposableBeanIfNecessary(beanName, bean, beanDefinition); addSingleton(beanName, bean); return bean; } private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) { // invokeAwareMethods if (bean instanceof Aware) { if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(this); } if (bean instanceof BeanClassLoaderAware){ ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } } // 1. 執行 BeanPostProcessor Before 處理 Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName); // 執行 Bean 對象的初始化方法 try { invokeInitMethods(beanName, wrappedBean, beanDefinition); } catch (Exception e) { throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e); } // 2. 執行 BeanPostProcessor After 處理 wrappedBean = applyBeanPostProcessorsAfterInitialization(bean, beanName); return wrappedBean; } @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (null == current) return result; result = current; } return result; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (null == current) return result; result = current; } return result; } }
bean instanceof Aware
,調用了三個接口方法,BeanFactoryAware.setBeanFactory(this)
、BeanClassLoaderAware.setBeanClassLoader(getBeanClassLoader())
、BeanNameAware.setBeanName(beanName)
,這樣就能通知到已經實現了此接口的類。ApplicationContextAwareProcessor
,此時在這個方法中也會被調用到具體的類實現,獲得一個 ApplicationContex 屬性。cn.bugstack.springframework.test.bean.UserDao
public class UserDao { private static Map<String, String> hashMap = new HashMap<>(); public void initDataMethod(){ System.out.println("執行:init-method"); hashMap.put("10001", "小傅哥"); hashMap.put("10002", "八杯水"); hashMap.put("10003", "阿毛"); } public void destroyDataMethod(){ System.out.println("執行:destroy-method"); hashMap.clear(); } public String queryUserName(String uId) { return hashMap.get(uId); } }
cn.bugstack.springframework.test.bean.UserService
public class UserService implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware { private ApplicationContext applicationContext; private BeanFactory beanFactory; private String uId; private String company; private String location; private UserDao userDao; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public void setBeanName(String name) { System.out.println("Bean Name is:" + name); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("ClassLoader:" + classLoader); } // ...get/set }
基礎配置,無BeanFactoryPostProcessor、BeanPostProcessor,實現類
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="userDao" class="cn.bugstack.springframework.test.bean.UserDao" init-method="initDataMethod" destroy-method="destroyDataMethod"/> <bean id="userService" class="cn.bugstack.springframework.test.bean.UserService"> <property name="uId" value="10001"/> <property name="company" value="騰訊"/> <property name="location" value="深圳"/> <property name="userDao" ref="userDao"/> </bean> </beans>
@Test public void test_xml() { // 1.初始化 BeanFactory ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml"); applicationContext.registerShutdownHook(); // 2. 獲取Bean對象調用方法 UserService userService = applicationContext.getBean("userService", UserService.class); String result = userService.queryUserInfo(); System.out.println("測試結果:" + result); System.out.println("ApplicationContextAware:"+userService.getApplicationContext()); System.out.println("BeanFactoryAware:"+userService.getBeanFactory()); }
測試結果
執行:init-method ClassLoader:sun.misc.Launcher$AppClassLoader@14dad5dc Bean Name is:userService 測試結果:小傅哥,騰訊,深圳 ApplicationContextAware:cn.bugstack.springframework.context.support.ClassPathXmlApplicationContext@5ba23b66 BeanFactoryAware:cn.bugstack.springframework.beans.factory.support.DefaultListableBeanFactory@2ff4f00f 執行:destroy-method Process finished with exit code 0
目前關於 Spring 框架的實現中,某些功能點已經越來趨向於完整,尤爲是 Bean 對象的生命週期,已經有了不少的體現。總體總結如圖 9-3