前言
手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】的第四篇实现了任务阶段 3- 初始化 bean 单例池 和 实现任务阶段 4- 完成依赖注入
个人主页:尘觉主页
个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力
在csdn获奖荣誉: csdn城市之星2名
Java全栈群星计划top前5
端午大礼包获得者
欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦
说明: 初始化 bean 单例池,并完成 getBean 方法 , createBean 方法
public WyxSpringApplicationContext(Class configClass) {
//通过扫描,得到 beanDefinition 的 map
beanDefinitionsByscan(configClass);
System.out.println(beanDefinitionMap);
//通过 beanDefinitionMap , 初始化 singletonObjects bean 单列池
Enumeration<String> keys = beanDefinitionMap.keys();
while (keys.hasMoreElements()) {
//得到 beanName
String beanName = keys.nextElement();
//通过 beanName 得到 beanDefinition
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if ("singleton".equalsIgnoreCase(beanDefinition.getScope())) {
//将该 bean 实例放入 singletonObjects
Object bean = createBean(beanDefinition);
singletonObjects.put(beanName, bean);
}
}
System.out.println("singletonObjects 单例池 = " + singletonObjects);
}
//先简单实现实现,后面在完善.
private Object createBean(BeanDefinition beanDefinition) {
//得到 bean 的类型
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();
}
//如果没有创建成功,返回 null
return null;
}
public Object getBean(String name) {
if(beanDefinitionMap.containsKey(name)) {
BeanDefinition beanDefinition = beanDefinitionMap.get(name);
//得到 bean 的 scope , 分别处理
if("singleton".equalsIgnoreCase(beanDefinition.getScope())) {
//单例,直接从 bean 单例池获取
return singletonObjects.get(name);
} else { //不是单例,则没有返回新的实例
return createBean(beanDefinition);
}
} else {
throw new NullPointerException("没有该 bean");
}
}
public class AppMain {
public static void main(String[] args) {
//创建我们的 spring 容器对象
HspSpringApplicationContext hspSpringApplicationContext =
new HspSpringApplicationContext(HspSpringConfig.class);
//通过 spring 容器对象, 获取 bean 对象
System.out.println(hspSpringApplicationContext.getBean("monsterService"));
System.out.println(hspSpringApplicationContext.getBean("monsterService"));
System.out.println(hspSpringApplicationContext.getBean("monsterService"));
}
}
● 代码实现, 说明,整个实现思路,就是参考 Spring 规范
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
//这里属性,可以参考思路完成,还是比较简单
//boolean required() default true;
}
@Component("monsterDao")
public class MonsterDao {
public void hi() {
System.out.println("hi 我是 monster Dao, select * from ....");
}
}
@Component("monsterService")
@Scope("prototype")
public class MonsterService implements InitializingBean {
@Autowired
private MonsterDao monsterDao;
public void m1() {
//调用 monsterDao 的 hi()
monsterDao.hi();
}
}
// 先简单实现实现,后面在完善. private Object createBean(BeanDefinition beanDefinition) {
// 得到 bean 的类型
Class clazz = beanDefinition.getClazz();
try
{
// 使用反射得到实例
Object instance = clazz.getDeclaredConstructor().newInstance();
// 完成依赖注入
for (Field declaredField : clazz.getDeclaredFields()) {
if (declaredField.isAnnotationPresent(Autowired.class)) {
// 处理@Autowired 注解的属性 required, 很简单,自己完成
// Autowired annotation =
declaredField.getAnnotation(Autowired.class);
// System.out.println(annotation.required());
// 如果该属性有@Autowired, 就进行组装
Object bean = getBean(declaredField.getName());
declaredField.setAccessible(true);// 因为属性是 private,需要暴破
declaredField.set(instance, bean);
}
}
return instance;
} catch(InstantiationException e){
e.printStackTrace();
} catch(IllegalAccessException e){
e.printStackTrace();
} catch(InvocationTargetException e){
e.printStackTrace();
} catch(NoSuchMethodException e){
e.printStackTrace();
}
// 如果没有创建成功,返回 null
return null;
}
public class AppMain {
public static void main(String[] args) {
//创建我们的 spring 容器对象
WyxSpringApplicationContext wyxSpringApplicationContext =
new WyxSpringApplicationContext(WyxSpringConfig.class);
//通过 spring 容器对象, 获取 bean 对象
//System.out.println(hspSpringApplicationContext.getBean("monsterService"));
//System.out.println(hspSpringApplicationContext.getBean("monsterService"));
//System.out.println(hspSpringApplicationContext.getBean("monsterService"));
MonsterService monsterService = (MonsterService)
wyxSpringApplicationContext.getBean("monsterService");
monsterService.m1();
}
}
本文完成了手动实现 Spring 底层机制实现任务阶段 3- 初始化 bean 单例池 和 实现任务阶段 4- 完成依赖注入后面会完成bean 后置处理器
手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】系列
手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器-准备篇【1】
手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器-准备篇【2】
手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器,实现任务阶段 2- 扫描将 bean 信息封装到 BeanDefinition 对象
热门专栏推荐
想学习vue的可以看看这个
java基础合集
数据库合集
redis合集
nginx合集
linux合集
等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持
欢迎大家加入我的社区 尘觉社区
文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读
如果帮助到您不妨3连支持一