public class XsmApplicationContext {
private Class configClass;
private ConcurrentHashMap<String,Object> singletonObjects=new ConcurrentHashMap<>();//单例池
private ConcurrentHashMap<String,BeanDefinition> beanDefinitionMap=new ConcurrentHashMap<>();
public XsmApplicationContext(Class configClass) {
this.configClass = configClass;
//ComponentScan注解--->扫描路径---》扫描---》Beandefinition--->BeanDefinitionMap
scan(configClass);
//在启动时把所有单例bean创建好
for(Map.Entry<String,BeanDefinition> entry:beanDefinitionMap.entrySet()){
String beanName=entry.getKey();
BeanDefinition beanDefinition=entry.getValue();
if(beanDefinition.getScope().equals("singleton")){
Object bean= createBean(beanDefinition); //单例bean
singletonObjects.put(beanName,bean);
}
}
}
//根据bean的生命周期创建对象
public Object createBean(BeanDefinition beanDefinition){
Class clazz = beanDefinition.getClazz();
try {
Object instance = clazz.getDeclaredConstructor().newInstance();
return instance;//返回实例对象
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
private void scan(Class configClass) {
if(configClass.isAnnotationPresent(ComponentScan.class)){
//解析配置类
//ComponentScan注解--->扫描路径---》扫描
ComponentScan declaredAnnotation = (ComponentScan) configClass.getDeclaredAnnotation(ComponentScan.class);
String path = declaredAnnotation.value(); //扫描路径 com.xiashiman.service
path=path.replace(".","/"); //把·替换成/---》 com/xiashiman/service
//扫描--->找出包下面的所有类
//类加载器
//Bootstrap----jre/lib
//Ext----->jre/ext/lib
//App----->classpath-----:E:\project\common\shousiCode\target\classes
ClassLoader classLoader=XsmApplicationContext.class.getClassLoader();//app类加载器
URL resource = classLoader.getResource(path);//通过路径获取资源
File file=new File(resource.getFile());
//判断是否是目录
if(file.isDirectory()){
File[] files = file.listFiles();//拿到目录下的所以文件
for (File f:files){
String fileName = f.getAbsolutePath(); //E:\project\common\shousiCode\target\classes\com\xiashiman\service\UserService.class
//判断是否是class文件
if(fileName.endsWith(".class")){
//截取com到.class前的部分
String className= fileName.substring(fileName.indexOf("com\\"), fileName.indexOf(".class"));
className=className.replace("\\","."); //替换成:com.xiashiman.service.UserService
//准备通过反射实例化对象
Class clazz=null;
try{
clazz=classLoader.loadClass(className); //反射获取类模板对象
if(clazz.isAnnotationPresent(Component.class)){
//表示当前类是一个bean
//解析类:判断是单例 还是原型
// BeanDefinition
Component componentAnntotaion= (Component) clazz.getDeclaredAnnotation(Component.class);
String beanName = componentAnntotaion.value();
BeanDefinition beanDefinition=new BeanDefinition();
beanDefinition.setClazz(clazz);
if(clazz.isAnnotationPresent(Scope.class)){
Scope scopeAnntation= (Scope) clazz.getDeclaredAnnotation(Scope.class);
beanDefinition.setScope(scopeAnntation.value());
}else{
beanDefinition.setScope("singleton");
}
beanDefinitionMap.put(beanName,beanDefinition);
}
}catch (ClassNotFoundException e){
e.printStackTrace();
}
}
}
}
}
}
public Object getBean(String beanName){
if(beanDefinitionMap.containsKey(beanName)){
BeanDefinition beanDefinition=beanDefinitionMap.get(beanName);
if(beanDefinition.getScope().equals("singleton")){
Object o=singletonObjects.get(beanName);
return o;
}else{
//创建bean对象 怎么创建呢
Object bean=createBean(beanDefinition);
return bean;
}
}else{
throw new NullPointerException("不存在对应的bean");
}
}
}