手写简单的Spring底层

本文介绍了Spring中常用的注解如@Autowired、@Component、@ComponentScan和@Scope,并展示了如何自定义应用上下文DjyApplicationContext来处理bean的定义、创建、依赖注入以及扫描组件。此外,还给出了一个DjyBeanPostProcessor的实例,用于展示后初始化处理。通过示例代码,详细解释了bean的生命周期和依赖查找过程。
摘要由CSDN通过智能技术生成

废话不多少直接上代码

spring 常用注解先定义一下

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
    String value() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
    String value() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
    String value() default "";
}

bean 定义

public class BeanDefinition {

    private Class type;

    private String scope;

    private boolean isLazy;


    public Class getType() {
        return type;
    }

    public void setType(Class type) {
        this.type = type;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public boolean isLazy() {
        return isLazy;
    }

    public void setLazy(boolean lazy) {
        isLazy = lazy;
    }
}
public interface BeanPostProcessor {

    default Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }


    default Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

此处是重点

public class DjyApplicationContext {

    private Class configClass;

    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap();
    private Map<String, Object> singletonObjects = new HashMap();
    private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();

    /**
     * 初始化
     *
     * @param configClass
     */
    public DjyApplicationContext(Class configClass) {
        this.configClass = configClass;
        //扫描
        scan(configClass);

        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
            String beanNme = entry.getKey();
            BeanDefinition beanDefinition = entry.getValue();
            if (beanDefinition.getScope().equals("singleton")) {
                Object bean = createBean(beanNme, beanDefinition);
                singletonObjects.put(beanNme, bean);
            }
        }

    }

    /**
     * 获得bean
     *
     * @param beanName
     * @return
     */
    public Object getBean(String beanName) {
        //不存在表示Bean不存在
        if (!beanDefinitionMap.containsKey(beanName)) {
            throw new NullPointerException("Bean不存在");
        }
        //根据bean的名称获取 bean的实体clazz
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);

        if (beanDefinition.getScope().equals("singleton")) {
            Object singleton = singletonObjects.get(beanName);
            if (null == singleton) {
                singleton = createBean(beanName, beanDefinition);
                singletonObjects.put(beanName, beanDefinition);
            }
            return singleton;
        } else {
            //原型bean ==>多例
            Object prototypeBean = createBean(beanName, beanDefinition);
            return prototypeBean;
        }
    }


    /**
     * 创建bean
     *
     * @param beanName
     * @param beanDefinition
     * @return
     */
    private Object createBean(String beanName, BeanDefinition beanDefinition) {
        Class clazz = beanDefinition.getType();
        Object instance = null;
        try {
            instance = clazz.getConstructor().newInstance();

            //此处进行依赖注入(AOP)
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(Autowired.class)) {
                    field.setAccessible(true);
                    //此处先根据类型查找 在根据名字查找
                    //此处省略 直接名字查找  有兴趣的小伙伴可自行尝试
                    field.set(instance, getBean(field.getName()));
                }
            }
            if (instance instanceof InitializingBean) {
                ((InitializingBean) instance).afterPropertiesSet();
            }
            new DjyBeanPostProcessor().postProcessAfterInitialization(instance, beanName);

            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                beanPostProcessor.postProcessAfterInitialization(instance, beanName);

            }


        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return instance;
    }


    /**
     * 扫描所有Bean
     *
     * @param configClass
     */
    private void scan(Class configClass) {
        if (configClass.isAnnotationPresent(ComponentScan.class)) {
            ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
            String path = componentScanAnnotation.value();
            path = path.replace(".", "/");


            ClassLoader classLoader = DjyApplicationContext.class.getClassLoader();
            URL resource = classLoader.getResource(path);
            File file = new File(resource.getFile());
            if (file.isDirectory()) {
                for (File f : file.listFiles()) {
                    String absolutePath = f.getAbsolutePath();
                    absolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
                    absolutePath = absolutePath.replace("\\", ".");
                    Class<?> clazz = null;
                    try {
                        clazz = classLoader.loadClass(absolutePath);

                        if (clazz.isAnnotationPresent(Component.class)) {
                            //判端当前类是否是实现BeanPostProcessor这个接口
                            if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
                                BeanPostProcessor instance = (BeanPostProcessor) clazz.getConstructor().newInstance();
                                beanPostProcessorList.add(instance);
                            } else {
                                // 通过注解获取当前bean的名字  spring 不定义会默认生成
                                Component componentAnnotation = clazz.getAnnotation(Component.class);
                                String beanName = componentAnnotation.value();
                                if ("".equals(beanName)) {
                                    beanName = Introspector.decapitalize(clazz.getSimpleName());
                                }

                                //如果存在Component ==>说明是bean  开始构建bean的定义
                                BeanDefinition beanDefinition = new BeanDefinition();
                                beanDefinition.setType(clazz);

                                if (clazz.isAnnotationPresent(Scope.class)) {
                                    Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
                                    String value = scopeAnnotation.value();
                                    beanDefinition.setScope(value);
                                } else {
                                    //单例
                                    beanDefinition.setScope("singleton");
                                }
                                beanDefinitionMap.put(beanName, beanDefinition);

                            }
                        }

                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    } catch (InstantiationException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    }

                }
            }
        }
    }

}
public interface InitializingBean {

    void afterPropertiesSet();
}

以下是业务测试代码

@Component
public class DjyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("1111");
        return bean;
    }
}

@Component
public class OrderService {

    public void test() {
        System.out.println("test");
    }
}

@Component("userService")
@Scope("prototype")
public class UserService implements InitializingBean {

    @Autowired
    private OrderService orderService;


    public void test() {
        System.out.println(orderService);
        System.out.println("test");
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("test1111");
    }
}

@ComponentScan("com.djy.service")
public class AppConfig {
}

以上是博主本人闲暇之余学习所记录,仅供大家学习参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一名技术极客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值