接上一篇[探究spring的底层实现原理1

上一篇从理论到源码讲到了以下四点

BeanFactory
Bean的整个生命周期
Bean的属性填充
依赖注入

这节就切合上一篇,手写一个简易版spring的小demo,看看我是怎样去实现的java

<谨供参考>

  • 应用程序上下文(启动类)
    1
    2
    3
    ClassPathXmlApplicationContext:xml配置文件方式
    AH8q3dGK2f2vLZVgbRfLTjQPySe2yRaJHs:注解方式
    SpringApplication:SpringBoot方式

模拟注解方式启动

  • 配置类,指定"spring"需要扫描的限定包路径

    1
    2
    3
    @ComponentScan("org.xiaowu.xiaowu.spring.xiaowu")
    public class AppConfig {
    }
  • 标注@Component的类则是需要被spring管理的

    1
    2
    3
    4
    5
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public [@interface](https://my.oschina.net/u/996807) Component {
    String value() default "";
    }
  • 配置该Bean为单例/prototype

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /**
    * @author 小五
    */
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Scope {
    Mode value() default Mode.SINGLETON;
    }
  • BeanDefinition 描述了一个 Bean 实例,实例包含属性值、构造方法参数值以及更多实现信息.这里我放了俩参数,scope和claszz

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /**
    * 同spring的BeanDefinition
    * BeanDefinition 描述了一个 Bean 实例,实例包含属性值、构造方法参数值以及更多实现信息
    */
    @Getter
    @Setter
    public class BeanDefinition {
    private Class clazz;
    private Mode scope;
    }
  • 等同spring的BeanPostProcessor.在初始化bean前后使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    /**
    * @author 小五
    * @date 2021/4/18 21:24
    */
    @Component
    public class BeanPostProcessorImpl implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
    if (beanName.equals("userService")){
    ((UserService)bean).setName("我是小五");
    }
    return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (beanName.equals("userService")) {
    // jdk动态代理方式实现aop
    Object proxyInstance = Proxy.newProxyInstance(BeanPostProcessorImpl.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    return method.invoke(bean,args);
    }
    });
    return proxyInstance;
    }
    return bean;
    }
    }
  • 等同spring的InitializingBean

    1
    2
    3
    4
    5
    6
    7
    8
    /**
    * @author 小五
    * @description: 同spring的InitializingBean
    * @date 2021/4/18 20:03
    */
    public interface InitializingBean {
    void afterPropertiesSet();
    }
  • 主要代码代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    /**
    * @author 小五
    */
    public class AH8q3dGK2f2vLZVgbRfLTjQPySe2yRaJHs {

    private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(16);

    // 单例池
    private Map<String, Object> singleTonMap = new ConcurrentHashMap<>(16);

    private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>(16);

    public AH8q3dGK2f2vLZVgbRfLTjQPySe2yRaJHs(Class configClazz) throws Exception {
    /**
    * 1. 获取AppConfig上ComponentScan的value值(路径)
    * 2. 用classlocader获取路径下所有类
    * 3. 遍历所有类,判断哪些是被@Component标注(即需被注入容器)
    * 4. 判断当前bean是否是单例的,如果是,创建完放到singleTonMap中(单例池)
    */
    if (configClazz.isAnnotationPresent(ComponentScan.class)) {
    ComponentScan componentScan = (ComponentScan) configClazz.getDeclaredAnnotation(ComponentScan.class);
    String path = componentScan.value();
    ClassLoader classLoader = AH8q3dGK2f2vLZVgbRfLTjQPySe2yRaJHs.class.getClassLoader();
    String filePath = StrUtil.replace(path, ".", "/");
    // 绝对路径
    URL url = classLoader.getResource(filePath);
    List<String> recursiveFiles = new ArrayList<>();
    // 递归查找该路径下所有类文件
    RecursiveFileUtils.recursiveFiles(url.getFile(),recursiveFiles);
    // 获取@Component的扫描路径
    for (String absolutePath : recursiveFiles) {
    String subPath = StrUtil.sub(absolutePath, absolutePath.indexOf(path), absolutePath.lastIndexOf(".class"));
    Class<?> aClass = classLoader.loadClass(subPath);
    // 判读是否标注@Component(是否需要被咱们"spring"管理)
    if (aClass.isAnnotationPresent(Component.class)) {
    // 如果BeanPostProcessor与aClass表示的类或接口相同,或者是参数aClass表示的类或接口的父类,则返回true。
    if (BeanPostProcessor.class.isAssignableFrom(aClass)){
    // todo 此创建BeanPostProcessor的方法不严谨,待改善
    BeanPostProcessor beanPostProcessor = (BeanPostProcessor) aClass.getDeclaredConstructor().newInstance();
    beanPostProcessors.add(beanPostProcessor);
    }
    Component componentAnnotation = aClass.getDeclaredAnnotation(Component.class);
    // value为空则取类名作为beanName
    String beanName = StrUtil.isEmpty(componentAnnotation.value()) ? StrUtil.lowerFirst(aClass.getSimpleName()) : componentAnnotation.value();
    BeanDefinition beanDefinition = new BeanDefinition();
    beanDefinition.setClazz(aClass);
    // 判断是单例还是原型,默认是单例的
    if (aClass.isAnnotationPresent(Scope.class)) {
    Scope scopeAnnotation = aClass.getDeclaredAnnotation(Scope.class);
    beanDefinition.setScope(scopeAnnotation.value());
    } else {
    beanDefinition.setScope(Mode.SINGLETON);
    }
    beanDefinitionMap.put(beanName, beanDefinition);
    }
    }
    // 判断是否需要放到单例池
    for (String beanName : beanDefinitionMap.keySet()) {
    BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
    if (beanDefinition.getScope() == Mode.SINGLETON) {
    // 二次判断,如果单例池已经有了,说明该bean有被其他bean依赖
    Object bean = singleTonMap.get(beanName);
    if (!Optional.ofNullable(bean).isPresent()){
    bean = createBean(beanName,beanDefinition);
    singleTonMap.put(beanName, bean);
    }
    }
    }
    } else {
    throw new RuntimeException("未被标注");
    }


    }

    private Object createBean(String beanName,BeanDefinition beanDefinition) {
    try {
    // 实例化
    Class clazz = beanDefinition.getClazz();
    Object newInstance = clazz.getDeclaredConstructor().newInstance();
    // 属性填充
    // todo 遍历当前bean的所有依赖对象,并判断是byname还是bytype等,这里先基于byname
    for (Field declaredField : clazz.getDeclaredFields()) {
    if (declaredField.isAnnotationPresent(Autowired.class)) {
    Object bean = getBean(declaredField.getName());
    if (!Optional.ofNullable(bean).isPresent()){
    throw new RuntimeException("getBean "+beanName+" 错误");
    }
    declaredField.setAccessible(true);
    declaredField.set(newInstance, bean);
    }
    }
    // todo 一堆Aware接口方法
    // 初始化bean之前
    for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
    beanPostProcessor.postProcessBeforeInitialization(newInstance,beanName);
    }
    // 初始化bean
    if (newInstance instanceof InitializingBean){
    ((InitializingBean)newInstance).afterPropertiesSet();
    }
    // 初始化bean之后
    for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
    beanPostProcessor.postProcessAfterInitialization(newInstance,beanName);
    }
    singleTonMap.put(beanName, newInstance);
    return newInstance;
    } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
    e.printStackTrace();
    }
    return null;
    }

    public Object getBean(String beanName) {
    BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
    if (beanDefinition != null) {
    if (beanDefinition.getScope() == Mode.SINGLETON) {
    Object bean = singleTonMap.get(beanName);
    return Optional.ofNullable(bean).isPresent()?bean:createBean(beanName,beanDefinition);
    } else {
    return createBean(beanName,beanDefinition);
    }
    }
    throw new RuntimeException("未找到当前bean对象");
    }
    }

测试一下看看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
* @author 小五
* @date 2021/4/18 16:25
*/
@Component
@Scope(Mode.SINGLETON)
public class UserService implements InitializingBean {
@Autowired
private OrderService orderService;
@Setter
@Getter
private String name;
public void test(){
System.out.println(orderService);
System.out.println(name);
}
@Override
public void afterPropertiesSet() {
System.out.println("执行afterPropertiesSet方法");
}
}

/**
* 1. AH8q3dGK2f2vLZVgbRfLTjQPySe2yRaJHs
* 2. BeanDefinition
* 3. BeanNameAware
* 4. InitializingBean
* 5. BeanPostProcessor
*/
//@SpringBootApplication
public class XiaowuSpringApplication {

public static void main(String[] args) throws Exception {
// ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("");
// AH8q3dGK2f2vLZVgbRfLTjQPySe2yRaJHs annotationConfigApplicationContext = new AH8q3dGK2f2vLZVgbRfLTjQPySe2yRaJHs(AppConfig.class);
// ConfigurableApplicationContext context = SpringApplication.run(XiaowuSpringApplication.class, args);
// UserService userService = (UserService) context.getBean("userService");
// userService.test();
AH8q3dGK2f2vLZVgbRfLTjQPySe2yRaJHs annotationConfigApplicationContext = new AH8q3dGK2f2vLZVgbRfLTjQPySe2yRaJHs(AppConfig.class);
UserService userService = (UserService) annotationConfigApplicationContext.getBean("userService");
userService.test();
}
}


执行afterPropertiesSet方法
org.xiaowu.xiaowu.spring.xiaowu.service.OrderService@5474c6c
null

源码仓库地址: 简易版spring demo