手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】【任务阶段4】
任务阶段1、2、3链接
一、实现任务阶段 1- 编写自己 Spring 容器,实现扫描包, 得到 bean 的 class 对象
二、实现任务阶段 2- 扫描将 bean 信息封装到 BeanDefinition 对象, 并放入到 Map
三、实现任务阶段 3- 初始化 bean 单例池,并完成 getBean 方法 , createBean 方法
四、实现任务阶段 4- 完成依赖注入
说明:整个实现思路,就是参考 Spring 规范
1.定义Autowired注解,实现了该注解的属性将会被进行依赖注入(看下面代码实现)
package com.hykedu.spring.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 程序员蛇皮
* @version 1.0
*/
@Target({ElementType.METHOD, ElementType.FIELD,})
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}
2.编辑CodeSnakeSpringApplicationContext类,在createBean方法增加识别Autowired注解进行依赖注入的功能
//完成createBean(BeanDefinition beanDefinition)方法
private Object createBean(BeanDefinition beanDefinition, String beanName) {
//得到Bean的clazz对象
Class clazz = beanDefinition.getClazz();
try {
//使用反射得到对象实例
Object instance = clazz.getDeclaredConstructor().newInstance();
//依赖注入
//1.遍历当前要创建的对象的所有字段
for (Field declaredField : clazz.getDeclaredFields()) {
//2.判断这个字段是否有@Autowired
if (declaredField.isAnnotationPresent(Autowired.class)) {
//3.得到这个字段的名字
String name = declaredField.getName();
System.out.println("字段名:" + name);
//4.通过getBean()获取要组装的对象
Object bean = getBean(name);
//5.进行组装
//私有属性需要进行反射暴破
declaredField.setAccessible(true);
declaredField.set(instance, bean);
}
}
System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------");
System.out.println("=====创建好实例=====" + instance);
if (instance != null) {
return instance;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return null;
}
3.在StudentDao类中定义hi()方法,在StudentService类中定义m1()方法,在m1()调用StudentDao类的hi()方法
StudentDao.java
package com.hykedu.spring.component;
import com.hykedu.spring.annotation.Component;
/**
* @author 程序员蛇皮
* @version 1.0
*/
@Component
public class StudentDao {
public void hi() {
System.out.println("StudentDao hi~");
}
}
StudentService.java
package com.hykedu.spring.component;
import com.hykedu.spring.annotation.Autowired;
import com.hykedu.spring.annotation.Component;
import com.hykedu.spring.annotation.Scope;
/**
* @author 程序员蛇皮
* @version 1.0
*/
@Scope(value = "prototype")
@Component
public class StudentService {
//这里我们使用自己的 @Autowired 来修饰属性
//表示该属性,是通过容器完成依赖注入
//我们这里实现按照名字进行组装
@Autowired
private StudentDao studentDao;
public void m1(){
studentDao.hi();
}
}
测试方法AppMain
package com.hykedu.spring;
import com.hykedu.spring.component.StudentDao;
import com.hykedu.spring.component.StudentService;
import com.hykedu.spring.ioc.CodeSnakeSpringApplicationContext;
import com.hykedu.spring.ioc.CodeSnakeSpringConfig;
/**
* @author 程序员蛇皮
* @version 1.0
*/
public class AppMain {
public static void main(String[] args) {
CodeSnakeSpringApplicationContext codeSnakeSpringApplicationContext = new CodeSnakeSpringApplicationContext(CodeSnakeSpringConfig.class);
StudentService studentService = (StudentService) codeSnakeSpringApplicationContext.getBean("studentService");
studentService.m1();
System.out.println("ok");
}
}
测试结果:StudentService中的StudentDao对象成功地进行了依赖注入
标签:BeanPostProcessor,spring,hykedu,StudentDao,Spring,import,机制,com,annotation From: https://blog.csdn.net/2301_77647448/article/details/141217702