Spring源码解析
2021-05-27 23:02
标签:而且 one hashmap 获取 try alac 完成 with interface 效仿原生AapplicationContext 简单的源码分为构造方法和getBean方法所以我们需要冲着些方法考虑 基本完成的代码如下 AapplicationContext 类如下 里面分为构造方法和getBean方法 扫描路径获得我们需要生成对象的范围所以需要一个注解 CompenentScan 以及AppConfig类 这样我们才知道我们需要把什么包下面的对象交给Spring管理 通过类加载器获得.class文件 遍历文件判断是否含有Component注解,这个注解表示生成的对象名称 Component注解 这里就需要把对象的beanName,class对象和是否为单列保存到一个map对象中去,因为如果不在构造方法中保存的话,在getBean方法中就需要在便利 所以需要一个存放class对象和是否为单列的一个新对象为beanDeefinition BeanDeefinition类为 和一个注解Scope 上面整个步骤为解析配置类方法 解析过后就需要实力化对象因为涉及多列和单列所以当为单列的时候需要一个单列池保存对象 多列的时候就通过反射创建对象所以把创建对象的方法抽为一个方法 通过初始化我们把所以的对象保存到了beanDeefinitionMap中??map获得对象并且存放单列池 如果为单列就去单列池中获取如果不是就直接创建对象 这就是非常简单的Spring Spring源码解析 标签:而且 one hashmap 获取 try alac 完成 with interface 原文地址:https://www.cnblogs.com/xiaoruirui/p/14807165.htmlpackage cn.jiedada.spring;
import java.io.File;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class JieDaDaApplicationContext {
private Class configClass;
//在getBean中通过名字找到对象
private Map
1.构造方法里面需要
JieDaDaApplicationContext context = new JieDaDaApplicationContext(AppConfig.class);
package cn.jiedada.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
String value() default "";
}
package cn.jiedada.test;
import cn.jiedada.spring.ComponentScan;
@ComponentScan("cn.jiedada.test")
public class AppConfig {
}
ComponentScan annotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
//扫秒路径
String path = annotation.value();//cn.jiedada
//通过类加载器获得文件路径
ClassLoader classLoader = JieDaDaApplicationContext.class.getClassLoader();
URL resource = classLoader.getResource(replace);
File file = new File(resource.getFile());
File[] files = file.listFiles();
package cn.jiedada.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
String value() default "";
}
private Map
for (File f : files) {
//文件路径
String filePath = f.getAbsolutePath();
//判断是否是含有.class
if (filePath.endsWith(".class")){
//获得真实路径
String realPath1 = filePath.substring(filePath.indexOf("cn"), filePath.indexOf(".class"));
//通过类加载器获得对象应为类加载器需要使用的路径不为cn/jiedada/test/Main需要转化
String fileRealPath = realPath1.replace("/", ".");
try {
Class clazz = classLoader.loadClass(fileRealPath);
//获得component类对象
//获得类对象需要判断多列和单列所以需要添加一个注解
//因为是通过getBean获得对象,所以不可能再去getBean中在遍历一次,所以我们需要把对象保存BeanDefinition
//又因为通过名字获得对象所以需要通过先存入Map对象的方式实现
if(clazz.isAnnotationPresent(Component.class)){
Component component = (Component) clazz.getAnnotation(Component.class);
//保存beanDefinitionMap
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setClazz(clazz);
if (clazz.isAnnotationPresent(Scope.class)){
//设置类的scope
Scope scope = (Scope) clazz.getAnnotation(Scope.class);
String value = scope.value();
beanDefinition.setScope(value);
}else {
beanDefinition.setScope("singleton");
}
beanDefinitionMap.put(component.value(),beanDefinition);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
package cn.jiedada.spring;
public class BeanDefinition {
private Class clazz;
private String scope;
public Class getClazz() {
return clazz;
}
public void setClazz(Class clazz) {
this.clazz = clazz;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
}
package cn.jiedada.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
String value() default "";
}
2.保存对象到单列池
//单列池,里面的是currenthashmap
private Map
//创建bean的方法
public Object createBean(String beanName,BeanDefinition beanDefinition){
Class clazz = beanDefinition.getClazz();
Object instance = null;
try {
instance = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return instance;
}
private void preInstantiateSingleton() {
for (Map.Entry
3.获得对象
public Object getBean(String beanName){
//获得beanDefinition
if (beanDefinitionMap.containsKey(beanName)){
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition.getScope().equals("singleton")){
//单列
Object o = singletonObjects.get(beanName);
return o;
}else {
//多列
Object bean = createBean(beanName, beanDefinition);
return bean;
}
}else {
throw new RuntimeException();
}
}
上一篇:Java 获取GUID
下一篇:C++ 获取GUID