30個(gè)類手寫Spring核心原理之依賴注入功能
在之前的源碼分析中我們已經(jīng)了解到,依賴注入(DI)的入口是getBean()方法,前面的IoC手寫部分基本流程已通。先在GPApplicationContext中定義好IoC容器,然后將GPBeanWrapper對(duì)象保存到Map中。在GPApplicationContext中設(shè)計(jì)兩個(gè)Map:factoryBeanObjectCache保存單例對(duì)象的緩存,factoryBeanInstanceCache保存GPBeanWrapper的緩存,變量命名也和原生Spring一致,這兩個(gè)對(duì)象的設(shè)計(jì)其實(shí)就是注冊(cè)式單例模式的經(jīng)典應(yīng)用。
- public class GPApplicationContext extends GPDefaultListableBeanFactory implements GPBeanFactory {
- private String [] configLocations;
- private GPBeanDefinitionReader reader;
- //用來(lái)保證注冊(cè)式單例的容器
- private Map<String,Object> factoryBeanObjectCache = new HashMap<String, Object>();
- //用來(lái)存儲(chǔ)所有的被代理過(guò)的對(duì)象
- private Map<String,GPBeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<String, GPBeanWrapper>();
- ...
- }
1 從getBean()方法開始
下面我們從完善getBean()方法開始:
- @Override
- public Object getBean(String beanName) {
- GPBeanDefinition beanDefinition = super.beanDefinitionMap.get(beanName);
- try{
- //生成通知事件
- GPBeanPostProcessor beanPostProcessor = new GPBeanPostProcessor();
- Object instance = instantiateBean(beanDefinition);
- if(null == instance){ return null;}
- //在實(shí)例初始化以前調(diào)用一次
- beanPostProcessor.postProcessBeforeInitialization(instance,beanName);
- GPBeanWrapper beanWrapper = new GPBeanWrapper(instance);
- this.factoryBeanInstanceCache.put(beanName,beanWrapper);
- //在實(shí)例初始化以后調(diào)用一次
- beanPostProcessor.postProcessAfterInitialization(instance,beanName);
- populateBean(beanName,instance);
- //通過(guò)這樣調(diào)用,相當(dāng)于給我們自己留有了可操作的空間
- return this.factoryBeanInstanceCache.get(beanName).getWrappedInstance();
- }catch (Exception e){
- // e.printStackTrace();
- return null;
- }
- }
2 instantiateBean()方法反射創(chuàng)建實(shí)例
- //傳一個(gè)BeanDefinition,就返回一個(gè)實(shí)例Bean
- private Object instantiateBean(GPBeanDefinition beanDefinition){
- Object instance = null;
- String className = beanDefinition.getBeanClassName();
- try{
- //因?yàn)楦鶕?jù)Class才能確定一個(gè)類是否有實(shí)例
- if(this.factoryBeanObjectCache.containsKey(className)){
- instance = this.factoryBeanObjectCache.get(className);
- }else{
- Class<?> clazz = Class.forName(className);
- instance = clazz.newInstance();
- this.factoryBeanObjectCache.put(beanDefinition.getFactoryBeanName(),instance);
- }
- return instance;
- }catch (Exception e){
- e.printStackTrace();
- }
- return null;
- }
3 populateBean()方法完成依賴注入
- private void populateBean(String beanName,Object instance){
- Class clazz = instance.getClass();
- if(!(clazz.isAnnotationPresent(GPController.class) ||
- clazz.isAnnotationPresent(GPService.class))){
- return;
- }
- Field [] fields = clazz.getDeclaredFields();
- for (Field field : fields) {
- if (!field.isAnnotationPresent(GPAutowired.class)){ continue; }
- GPAutowired autowired = field.getAnnotation(GPAutowired.class);
- String autowiredBeanName = autowired.value().trim();
- if("".equals(autowiredBeanName)){
- autowiredBeanName = field.getType().getName();
- }
- field.setAccessible(true);
- try {
- field.set(instance,this.factoryBeanInstanceCache.get(autowiredBeanName). getWrappedInstance());
- } catch (IllegalAccessException e) {
- // e.printStackTrace();
- }
- }
- }
4 GPBeanPostProcessor后置處理器
原生Spring中的BeanPostProcessor是為對(duì)象初始化事件設(shè)置的一種回調(diào)機(jī)制。這個(gè)Mini版本中只做說(shuō)明,不做具體實(shí)現(xiàn),感興趣的“小伙伴”可以繼續(xù)深入研究Spring源碼。
- package com.tom.spring.formework.beans.config;
- public class GPBeanPostProcessor {
- //為在Bean的初始化之前提供回調(diào)入口
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception {
- return bean;
- }
- //為在Bean的初始化之后提供回調(diào)入口
- public Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {
- return bean;
- }
- }
至此,DI部分就手寫完成了,也就是說(shuō)完成了Spring的核心部分。“小伙伴們”是不是發(fā)現(xiàn)其實(shí)還是很簡(jiǎn)單的?