手写模拟Spring底层原理

本文只是粗略的写一下spring的大概的过程,具体如果要写完那是不可能的事情

介绍:

        一、定义一个自己的ApplicationContext,这个类是核心,构造方法执行的是通过传入的AppConfig类上定义的@ComponentScan注解的value来扫

描,加一个以beanName为key,BeanDefinition为value的map中(BeanDefinition定义bean的各种

属性,需要实例化的时候用到);spring的非懒加载的单例bean都是启动初始化好的,所以构造方

法接下来做的事情就是检测@scope注解,如果value是singleton实例化加入到单例map中;扫描需

要把beanPostProcessor加到一个list中(后续bean的初始化需要执行到它内部方法回调)

        二、doCreateBean()方法就是根据之前扫描加入到beanDefinitionMap中的beanDefinition来进行bean的创建;

        首先,根据bean的名字得到一个beanDefinition,调用反射的newInstance()方法实例化对象

        接着进行依赖注入,判断属性上是否存在@Autowired注解作为根据

        再判断初始化的bean是否实现了BeanNameAware或者其他Aware的在此时调用它内部定义的方法

        执行之前定义的beanPostProcessorList的单个的beanPostProcessor的postProcessBeforeInitialization()方法

        判断是否实现了InitializingBean接口如果实现了就在此时调用其内部定义的afterPropertiesSet()方法

执行之前定义的beanPostProcessorList的单个的beanPostProcessor的postProcessAfterInitialization()方法,最后通过动态代理返回代理的对象

        三、getBean()方法就是先根据beanName看看beanDefinitionMap是否有定义,没有定义那就

是没有;再根据beanDefinition的scope属性判断是什么类型的,如果是prototype则需要在此时调
用doCreateBean()方法获取bean,如果是其他则在单例池singletonMap中获取,下面是具体代码:

程序调用测试

package com.gaorufeng;

import com.gaorufeng.service.UserService;
import com.spring.GaorufengApplicationContext;

public class Test {

	public static void main(String[] args) {
		GaorufengApplicationContext applicationContext = new GaorufengApplicationContext(AppConfig.class);
		UserService userService = (UserService) applicationContext.getBean("userService");
		userService.print();
	}
}

配置AppConfig扫描的路径

package com.gaorufeng;

import com.spring.ComponentScan;

@ComponentScan("com.gaorufeng.service")
public class AppConfig {

}

下面是核心类ApplicationContext

package com.spring;

import java.beans.Introspector;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GaorufengApplicationContext {
	
	private Map beanDefinitionMap = new HashMap();
	private Map singletonMap = new HashMap();
	private List beanPostProcessorList = new ArrayList();

	public GaorufengApplicationContext(Class appConfigClass) {
		// 扫描(把所有加了@Component注解的加到一个以beanName为key,BeanDefinition为value的map中)
		scan(appConfigClass);
		// 初始化单例bean,加到单例的singletonMap中
		for (Map.Entry entry : beanDefinitionMap.entrySet()) {
			Class clazz = entry.getValue().getClass();
			// 没有@Scope注解,或者有这个注解,但不是prototype的值,都会加到单例的singletonMap中
			if (!clazz.isAnnotationPresent(Scope.class) || !"prototype".equals(clazz.getAnnotation(Scope.class).value())) {
				singletonMap.put(entry.getKey(), doCreateBean(entry.getKey()));
			}
		}
	}
	
	private void scan(Class appConfigClass) {
		if (!appConfigClass.isAnnotationPresent(ComponentScan.class)) {
			throw new RuntimeException("AppConfig类上没有加@ComponentScan注解");
		}
		ComponentScan componentScanAnnotation = (ComponentScan) appConfigClass.getAnnotation(ComponentScan.class);
		if (componentScanAnnotation.value() == null || "".equals(componentScanAnnotation.value())) {
			throw new RuntimeException("AppConfig类上没有指定ComponentScan的扫描路径");
		}
		String path = componentScanAnnotation.value();
		path = path.replace(".", "/");
		ClassLoader classLoader = GaorufengApplicationContext.class.getClassLoader();
		File file = new File(classLoader.getResource(path).getFile());
		try {
			for (String classPath : getClassPath(file, new ArrayList())) {
				Class loadClass = classLoader.loadClass(classPath);
				// 判断有没有加@Componennt注解
				if (loadClass.isAnnotationPresent(Component.class)) {
					// 判断有没有实现BeanPostProcessor接口的
					if (BeanPostProcessor.class.isAssignableFrom(loadClass)) {
						beanPostProcessorList.add((BeanPostProcessor) loadClass.getConstructor().newInstance());
					}
					
					BeanDefinition beanDefinition = new BeanDefinition();
					beanDefinition.setType(loadClass);
					
					Component componentAnnotation = loadClass.getAnnotation(Component.class);
                    String beanName = componentAnnotation.value();
                    if ("".equals(beanName)) {
                        beanName = Introspector.decapitalize(loadClass.getSimpleName());
                    }
                    if (loadClass.isAnnotationPresent(Scope.class)) {
                    	beanDefinition.setScope(loadClass.getAnnotation(Scope.class).value());
                    } else {
                    	beanDefinition.setScope("singleton");
                    }
                    beanDefinitionMap.put(beanName, beanDefinition);
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 通过传入文件
	 * @param file
	 * @param classPathList
	 * @return
	 */
	public List getClassPath(File file, List classPathList) {
		if (file.isDirectory()) {
			for (File f : file.listFiles()) {
				classPathList.addAll(getClassPath(f, new ArrayList()));
			}
		} else {
			String absolutePath = file.getAbsolutePath();
			absolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
			classPathList.add(absolutePath.replace("\\", "."));
		}
		return classPathList;
	}
	
	
	public Object getBean(String beanName) {
		if (!beanDefinitionMap.containsKey(beanName)) {
			throw new RuntimeException("扫描没有发现该名称的bean对象");
		}
		BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
		if ("prototype".equals(beanDefinition.getScope())) {
			return doCreateBean(beanName);
		} else {
			Object object = singletonMap.get(beanName);
			if (object == null) {
				object = doCreateBean(beanName);
				singletonMap.put(beanName, object);
			}
			return object;
		}
	}
	
	/**
	 * 创建bean对象
	 * @param beanName
	 * @return
	 */
	private Object doCreateBean(String beanName) {
		BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
		if (beanDefinition == null) {
			throw new RuntimeException("没有找到beanName对应的的beanDefinition,无法创建bean");
		}
		Object newInstance = null;
		
		Class clazz = beanDefinition.getType();
		try {
			newInstance = clazz.getConstructor().newInstance();
			
			// 属性依赖注入
			for (Field field : clazz.getDeclaredFields()) {
				// 有加@Autowired注解的进行属性注入
				if (field.isAnnotationPresent(Autowired.class)) {
					field.setAccessible(true);
					field.set(newInstance, getBean(field.getName()));
				}
			}
			if (newInstance instanceof BeanNameAware) {
				((BeanNameAware)newInstance).setBeanName(beanName);
			}
			
			// 执行beanPostProcessor的postProcessBeforeInitialization方法
			for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
				// 可以在postProcessBeforeInitialization方法中创建newInstance的代理对象重新赋值给newInstance
				newInstance = beanPostProcessor.postProcessBeforeInitialization(newInstance, beanName);
			}
			if (newInstance instanceof InitializingBean) {
				((InitializingBean)newInstance).afterPropertiesSet();
			}
			// 执行beanPostProcessor的postProcessAfterInitialization方法
			for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
				newInstance = beanPostProcessor.postProcessAfterInitialization(newInstance, beanName);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return newInstance;
	}
}

代码地址:粗略实现spring创建bean-其它文档类资源-CSDN下载

你可能感兴趣的:(spring,spring)