手写模拟Spring启动时的操作,了解BeanDefinition和BeanPostProcessor.
Bean信息的封装类,其中包含Bean的类型、作用范围(单例、原型)、是否懒加载等
Spring启动时会把所有的Bean都封装为BeanDefinition
BeanPostProcessor是Spring提供的接口,如果类实现了该接口表示在所有bean创建时,会执行该类中的初始化前和初始化后操作。
这是Spring中非常重要的机制,Aop就是通过BeanPostProcessor实现的
需要注意的是,BeanPostProcessor对所有Bean生效,而初始化、回调这些接口只对实现了这些接口的Bean生效。
通过BeanPostProcessor创建代理类,并将代理类返回,替换掉原先的普通对象,这样创建出的Bean就是代理对象。、
其中主要包含了两个对外的方法:
public class RxwsApplicationContext {
private Class configClass;
//存放所有BeanDefinition
private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
//单例池
private Map<String, Object> singletonObjects = new HashMap<>();
//存放所有BenaPostProcessor
private List<BeanPostProcessor> beanPostProcessorList = new LinkedList<>();
public RxwsApplicationContext(Class configClass) throws Exception {
this.configClass = configClass;
//扫描Bean
scanBean();
//实例化Bean
for (String key : beanDefinitionMap.keySet()) {
BeanDefinition beanDefinition = beanDefinitionMap.get(key);
if ("singleton".equals(beanDefinition.getScope())) {
Object bean = createBean(key, beanDefinition);
singletonObjects.put(key, bean);
}
}
}
/**
* 获取Bean
*
* @param beanName
* @return
*/
public Object getBean(String beanName) throws Exception {
if (!beanDefinitionMap.containsKey(beanName)) {
throw new NullPointerException("Bean不存在");
}
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if ("singleton".equals(beanDefinition.getScope())) {
//单例Bean从单例池中拿
Object singletonBean = singletonObjects.get(beanName);
if (singletonBean == null) {
//依赖注入的时候可能作为属性的bean还没有创建
singletonBean = createBean(beanName, beanDefinition);
singletonObjects.put(beanName, singletonBean);
}
return singletonBean;
} else {
Object prototypeBean = createBean(beanName, beanDefinition);
return prototypeBean;
}
}
}
大部分功能和机制都是在创建bean时进行处理的。 具体就是在创建后逐个去判断有没有实现某个接口,然后调用接口的方法
private Object createBean(String beanName, BeanDefinition beanDefinition) throws Exception {
Class clazz = beanDefinition.getType();
Object instance = null;
instance = clazz.getConstructor().newInstance();
//依赖注入
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {
if (field.isAnnotationPresent(Autowire.class)) {
field.setAccessible(true);
field.set(instance, getBean(field.getName()));
}
}
//初始化前的操作
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
instance = beanPostProcessor.postProcessBeforeInitialization(instance, beanName);
}
//初始化 判断Bean是否实现了InitializingBean接口
if (instance instanceof InitializingBean) {
((InitializingBean) instance).afterPropertiesSet();
}
//初始化后的操作
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
instance = beanPostProcessor.postProcessAfterInitialization(instance, beanName);
}
//检查回调,以BeanNameAware为例
if (instance instanceof BeanNameAware) {
((BeanNameAware) instance).setBeanName(beanName);
}
return instance;
}
扫描包,扫描是从Target中拿到class文件,然后加载为类去操作的,扫描是就将Bean添加到上文提到的BeanDefinitionMap 、单例池 、 BeanProcessorList
private void scanBean() throws Exception {
if (configClass.isAnnotationPresent(ComponentScan.class)) {
ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
String path = componentScanAnnotation.value();
path = path.replace(".", "/");
//通过类加载器从target中获取所有class文件
ClassLoader appClassLoader = RxwsApplicationContext.class.getClassLoader();
URL resource = appClassLoader.getResource(path);
File files = new File(resource.getFile());
if (files.isDirectory()) {
for (File file : files.listFiles()) {
//D:\package\workspace\idea\mySpring\target\classes\rxws\UserService.class
String absolutePath = file.getAbsolutePath();
absolutePath = absolutePath.substring(absolutePath.indexOf("rxws"), absolutePath.indexOf(".class"));
//rxws.OrderService
absolutePath = absolutePath.replace("\\", ".");
//将文件加载进来成为类
Class<?> clazz = appClassLoader.loadClass(absolutePath);
//判断类有没有添加component注解,没有添加注解的不做处理
if (clazz.isAnnotationPresent(Component.class)) {
//如果类实现了BeanPostProcessor接口,则放入BeanPostProcessorList不放入单例池
if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
//如果类实现了BeanPostProcessor接口,则放入beanProcessor集合中
BeanPostProcessor beanPostProcessor = (BeanPostProcessor) clazz.getConstructor().newInstance();
beanPostProcessorList.add(beanPostProcessor);
} else {
BeanDefinition beanDefinition = new BeanDefinition();
String beanName = getBeanName(clazz);
//判断是单例还是原型
if (clazz.isAnnotationPresent(Scope.class)) {
//根据值判断是不是单例
Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
String scopeValue = scopeAnnotation.value();
beanDefinition.setScope(scopeValue);
} else {
beanDefinition.setScope("singleton");
}
//将bean存入map
beanDefinition.setType(clazz);
beanDefinitionMap.put(beanName, beanDefinition);
}
}
}
}
}
}
生成BeanName,Spring可以帮我们生成beanName,用户也可以自己指定
private String getBeanName(Class clazz) throws Exception {
Component componentAnnotation = (Component) clazz.getAnnotation(Component.class);
String beanName = componentAnnotation.name();
if ("".equals(beanName)) {
//JDK提供的方法,根据类名首字母小写生成一个名称
beanName = Introspector.decapitalize(clazz.getSimpleName());
}
return beanName;
}
因篇幅问题不能全部显示,请点此查看更多更全内容