package src.springCode.spring;
import java.beans.Introspector;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class ApplicationContext {
private Class configClass;
private ConcurrentHashMap<String,BeanDefinition> concurrentHashMap=new ConcurrentHashMap();//存放所有扫描对象
private ConcurrentHashMap<String,BeanDefinition> singleConcurrentHashMap=new ConcurrentHashMap();//单例池,共用一个对象
private List<BeanPostProcessor> beanList=new ArrayList<>();//存储使用BeanPostProcessor的对象
public ApplicationContext(Class configClass) throws ClassNotFoundException, InvocationTargetException,
NoSuchMethodException, InstantiationException, IllegalAccessException {
this.configClass=configClass;
//扫描
if (configClass.isAnnotationPresent(ComponentScan.class)) {
ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
String path = componentScanAnnotation.value();//扫描路径
path = path.replace(".", "/");
ClassLoader classLoader = ApplicationContext.class.getClassLoader();
URL resource = classLoader.getResource(path);//由相对路径获取绝对路径
File file=new File(resource.getFile());
if(file.isDirectory()){
File[] files = file.listFiles();
for (File f : files) {
String absolutePathName = f.getAbsolutePath();
String src = absolutePathName.substring(absolutePathName.indexOf("src"), absolutePathName.lastIndexOf(".class"));
src= src.replace("\\", ".");
if (f.getName().endsWith(".class")) {
Class<?> aClass = classLoader.loadClass(src);
if (aClass.isAnnotationPresent(Component.class)) {
//表示该类实现了BeanPostProcessor接口
if(BeanPostProcessor.class.isAssignableFrom(aClass)){ //因为aClass不为对象,不能用instanceof
BeanPostProcessor instance = (BeanPostProcessor) aClass.newInstance();
beanList.add(instance);
}
Component annotation = aClass.getAnnotation(Component.class);
String beanName= annotation.value();
if (beanName.equals("")) {
beanName= Introspector.decapitalize(aClass.getSimpleName());
}
//BeanDefinition
BeanDefinition beanDefinition=new BeanDefinition();
beanDefinition.setType(aClass);
if (aClass.isAnnotationPresent(Scope.class)) {
String value = aClass.getAnnotation(Scope.class).value();
beanDefinition.setScope(value);
}else{
beanDefinition.setScope("singleton");
}
concurrentHashMap.put(beanName,beanDefinition);
}
}
}
}
}
//创建单例bean
for (String key : concurrentHashMap.keySet()) {
BeanDefinition beanDefinition = concurrentHashMap.get(key);
if (beanDefinition.getScope().equals("singleton")) {
BeanDefinition bean = (BeanDefinition) createBean(key, beanDefinition);
singleConcurrentHashMap.put(key,bean);
}
}
}
public Object createBean(String beanName,BeanDefinition beanDefinition) throws NoSuchMethodException,
IllegalAccessException, InvocationTargetException, InstantiationException {
Class type = beanDefinition.getType();
Object instance= type.getConstructor().newInstance();
//简单版依赖注入
for (Field f : type.getDeclaredFields()) {
if(f.isAnnotationPresent(Autowired.class)){
f.setAccessible(true);
f.set(instance,getBean(f.getName()));
}
}
//Aware回调
if (instance instanceof BeanNameAware) {
((BeanNameAware)instance).setBeanName(beanName);
}
//初始化之前
for (BeanPostProcessor beanPostProcessor : beanList) {
beanPostProcessor.postProcessBeforeInitialization(beanName,beanDefinition);
}
//field值初始化
if (instance instanceof InitializingBean) {
((InitializingBean)instance).afterPropertiesSet();
}
//初始化之后
for (BeanPostProcessor beanPostProcessor : beanList) {
instance = (BeanDefinition) beanPostProcessor.postProcessAfterInitialization(beanName, beanDefinition);
}
//BeanPostProcessor 初始化后 AOP
return instance;
}
public BeanDefinition getBean(String beanNme) throws InvocationTargetException, NoSuchMethodException,
InstantiationException, IllegalAccessException {
BeanDefinition beanDefinition = concurrentHashMap.get(beanNme);
if (beanDefinition==null) {
throw new NullPointerException();
}else{
if (beanDefinition.getScope().equals("singleton")) {
BeanDefinition bean = singleConcurrentHashMap.get(beanNme);
if (bean==null) {
bean= (BeanDefinition) createBean(beanNme, beanDefinition);
singleConcurrentHashMap.put(beanNme,bean);//重新放入单例池
}
return bean;
}
else {
//多例bean
return (BeanDefinition) createBean(beanNme,beanDefinition);
}
}
}
}
SpringBoot底层原理
最新推荐文章于 2024-07-15 22:35:15 发布