在上一篇的基础上实现另一个功能 自动依赖注入 也就是平常用的最多的@Autowired注解
本篇将会实现@Autowired注解 实现对bean进行自动注入
核心流程
首先 先整理一下依赖注入的流程 核心流程就是
BeanFactory扫描指定包路径下所有类 然后根据带@Compoent注解的类创建实例 扔到beanMap当中 (无参构造)
依赖注入 将beanMap中每个bean遍历 例如userservice实例 检查字段中是否带有@Autowired注解
找到需要注入的字段后 会根据字段类型以及字段名 去beanMap中找到对应的实例
找到后 将这个字段的值设置为找到的实例(利用反射)
操作待补 电脑丢公司了....20250325 8:49
接下来一步一步来 这里我已经写好了程序
创建注解
在Annotion包里创建我们需要的Autowired注解
package com.dms.shanshan.core.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}
这个注解允许被用在字段上--@Target(ElementType.FIELD)
接下来说依赖注入的逻辑
修改BeanFactory--之前的包扫描逻辑仍然不变 在此基础上 新增一个依赖注入方法injectDependcy()
这个方法有以下作用
遍历beanMap当中的每个bean,然后扫描bean的字段field
对于每个字段 如果字段上带有Autowired注解,就根据字段类型在beanMap当中获取相应的bean
赋值给字段 实现依赖注入 不用手动创建依赖对象
上代码
public BeanFactory(String basePackage) throws InstantiationException, IllegalAccessException {
scanBean(basePackage);
injectDependcy();
}
在beanfactory构造器中新增依赖注入方法
public void injectDependcy(){
//扫描所有bean
for (Object bean:beansMap.values()){
//扫描所有bean的字段
for (Field field:bean.getClass().getDeclaredFields()){
if (field.isAnnotationPresent(Autowired.class)){
//获取字段类型
Class<?> fieldType=field.getType();
//从beanMap中获取依赖的bean
Object dependencyBean=beansMap.get(fieldType.getSimpleName());
if(dependencyBean!=null){
try{
//允许访问私有
field.setAccessible(true);
//将字段赋值
field.set(bean, dependencyBean);
}catch (Exception e){
System.out.println("出现错误");
}
}
}
}
}
}
依赖注入方法具体实现
这个方法比较简单 就不过多叙述 看代码即可
补充
injectDependcy()方法
当中字段使用的方法解释field.setAccessible(true)
和field.set(bean, dependencyBean);
查看set方法源码
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).set(obj, value);
}
解释:
先访问检查 查看是否允许访问 如果允许 就给该对象字段设置value
第一个参数obj是需要设置值的对象字段名,第二个参数value就是这个对象的值 通过这个方法 可以给相应的bean的字段设置值
后记
仓库地址(不断更新):
全系列:杜明珅的手搓spring迷你框架系列