Spring加载配置类大概过程
- 读取配置类
- 扫描配置类,判断配置类中是否包含ComponentScan注解
- 根据直接中的路径,以及Spring上下文的类加载器,获取到当前类路径下的文件
- 将该路径下的文件进行循环遍历
- 判断文件中是否包含Component注解
- 如果包含,以beanName为key, BeanDefinition为vlaue,存放到BeanDefinitionMap中。
Spring获取对象的大概过程
- 根据传入的beanName,判断beanDefinitionMap中是否存在,如果不存在则抛出异常
- 判断该bean是单例还是原型
- 如果是单例则去单例池中获取,如果是原型则直接创建。
Spring Aop大概实现过程
- 在扫描包,创建Bean之前,会判断该类是否实现BeanPostProcessor这个接口
- 如果实现了此接口会将此接口存储到beanPostProcessorList集合中。
- 当bean创建完成之后,可以借助**postProcessBeforeInitialization(初始化之前)或者postProcessAfterInitialization(初始化之后)**执行Aop中所需要执行的方法。
加载配置类代码
- 创建一个有参构造函数
public wwhApplicationContext(Class configClass) {
this.configClass = configClass;
scan(configClass);
for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
String beanName = entry.getKey();
BeanDefinition beanDefinition = entry.getValue();
if (beanDefinition.getScope().equals("singleton")) {
Object bean = createBean(beanName, beanDefinition);
singletonObjects.put(beanName, bean);
}
}
}
2.扫描方法
/**
* 1、解析传进来的class对象,得到扫描路径
* 2、遍历路径下的所有文件
* 3、加载每一个文件得到class对象
* 4、判断是否含有Component注解
* 5、根据Component注解获取bean的名字,得到一个BeanDefinition对象,存储到BeanDefinitionMap中
* @param configClass
*/
private void scan(Class configClass) {
//扫描配置类,判断配置类中是否有ComponentScan注解
if (configClass.isAnnotationPresent(ComponentScan.class)) {
ComponentScan componentScan = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
String path = componentScan.value();
path = path.replace(".", "/");
//通过类加载器获取当前类的路径
ClassLoader classLoader = wwhApplicationContext.class.getClassLoader();
URL resources = classLoader.getResource(path);
//通过类路径获取当前文件夹下的文件
File file = new File(resources.getFile());
if (file.isDirectory()) {
for (File f : file.listFiles()) {
String absolutePath = f.getAbsolutePath();
absolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
absolutePath = absolutePath.replace("\\", ".");
try {
Class<?> clazz = classLoader.loadClass(absolutePath);
//如果有Component注解,是一个bean
if (clazz.isAnnotationPresent(Component.class)) {
Component componentAnnotation = clazz.getAnnotation(Component.class);
String beanName = componentAnnotation.value();
//判断这个Bean是都实现BeanPostProcessor接口
//isAssignableFrom判断的是BeanPostProcessor和clazz是否相同或是另一个类的超类或者接口
if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
BeanPostProcessor beanPostProcessor = (BeanPostProcessor) clazz.getConstructor().newInstance();
beanPostProcessorList.add(beanPostProcessor);
}
//如果Component注解中未填写bean名称,则借助系统自动生成一个名字
if ("".equals(beanName)) {
beanName = Introspector.decapitalize(clazz.getSimpleName());
}
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setType(clazz);
//判断这个bean是否为单例
if (clazz.isAnnotationPresent(Scope.class)) {
Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
String value = scopeAnnotation.value();
beanDefinition.setScope(value);
}else {
beanDefinition.setScope("singleton");
}
beanDefinitionMap.put(beanName, beanDefinition);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
3.创建Bean
private Object createBean( String beanName, BeanDefinition beanDefinition) {
Class clazz = beanDefinition.getType();
Object instance = null;
try {
instance = clazz.getConstructor().newInstance();
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Autowired.class)) {
field.setAccessible(true);
field.set(instance, getBean(field.getName()));
}
}
if (instance instanceof BeanNameAware) {
((BeanNameAware) instance).setBeanName(beanName);
}
//Bean定义前置处理器,创建每一个Bean的时候都会调用该方法
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
//返回代理对象
instance = beanPostProcessor.postProcessBeforeInitialization(beanDefinition, beanName);
}
//如果Bean实现了InitializingBean接口,创建Bean的时候会调用该方法
//instanceof 判断实例对象,可以判断instance对象是否是InitializingBean类的或接口或其子类接口的实例
if (instance instanceof InitializingBean) {
((InitializingBean) instance).afterPropertiesSet();
}
//Bean定义后置处理器,创建每一个Bean的时候都会调用该方法
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
//返回代理对象
instance = beanPostProcessor.postProcessAfterInitialization(beanDefinition, beanName);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return instance;
}
4.获取Bean
public Object getBean(String beanName) {
//如果在beandefinitionMap中没有,说明传入的beanName是错误的
if (!beanDefinitionMap.containsKey(beanName)) {
throw new NullPointerException();
}
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
//判断bean是单例的还是原型的
if (beanDefinition.getScope().equals("singleton")) {
//如果是单例bean直接去单例池中获取
Object o = singletonObjects.get(beanName);
if (o == null) {
o = createBean(beanName, beanDefinition);
singletonObjects.put(beanName, o);
}
return o;
} else {
// 如果是原型,直接创建
return createBean(beanName, beanDefinition);
}
}