Spring探秘--开发自己的Spring框架之IOC

Spring探秘–开发自己的Spring框架之IOC

Spring作为JAVA最著名的框架之一很多人一定都很好奇Spring是怎么实现,因此通过这篇文章会介绍如何我是怎么自己实现Spring里的IOC功能的,相关代码请见下面的Git地址:

首先上Git:
https://github.com/qmhu/myspring

如果觉得可以求加星哦!!!


测试代码

获取bean

AnnotationApplicationContext applicationContext = new AnnotationApplicationContext("content-test.xml");
Teacher teacher = (Teacher) applicationContext.getBean("teacher");
System.out.println(teacher.toString());

在XML里配置Bean

<bean id="teacher" class="my.bean.Teacher">
    <property id="id" value="123"/>
    <property id="name" value="xiaowang"/>
</bean>

<bean id="student" class="my.bean.Student">
    <property id="id" value="333"/>
    <property id="name" value="student name"/>
</bean>

<component-scan base-package="my" />

用annotation配置Bean和field(field spring里没有。。。)

@Service
public class Country {

    @Field(value = "123")
    private int id;

    @Field(value = "countryname")
    private String name;

可以看到基本跟使用spring是差不多的。

基本概念

IOC:依赖注入,我的理解是通过配置来帮助程序管理依赖,有点data driven的意思。
Container:Spring里的container是指spring创建出来的bean的lifecycle都是被container统一配置和管理的。
Bean:Spring创建出来的对象。
BeanDefinition:Spring里定义一个对象的属性。
BeanProperty:Bean的property。
ApplicationContext:Spring暴露给用户的类。
BeanFactory:负责创建Bean的factory
BeanDefinitionLoader:负责load BeanDefinition的类
AutowireBeanFactory:负责自动inject成员变量的类

加载BeanDefinition

通过BeanDefinitionXMLLoader加载BeanDefinition再注册到BeanFactory里

beanDefinationLoader = new BeanDefinationXMLLoader();
beanDefinationLoader.loadBeanDefinations(configName);

for (BeanDefinition beanDefinition : beanDefinationLoader.getBeanDefinitions()){
    beanFactory.registerBeanDefinition(beanDefinition);
}

GetBean

getBean会首先从beanCache里看是否已有构建好的bean,如果没有则通过BeanDefinition创建出Bean对象,放入beanCache再返回。

public Object getBean(String name) {
     Object bean = beanCache.get(name);
     if (bean != null) {
         return bean;
     }

     BeanDefinition beanDefinition = beanDefinitionHashMap.get(name);
     String beanClass = beanDefinition.getBeanClass();
     try {
         Class className = Class.forName(beanClass);
         bean = className.newInstance();
         this.applyPropertyValues(bean, beanDefinition);
     } catch (ClassNotFoundException e) {
         e.printStackTrace();
     } catch (InstantiationException e) {
         e.printStackTrace();
     } catch (IllegalAccessException e) {
         e.printStackTrace();
     } catch (Exception e) {
         e.printStackTrace();
     }

     if (bean != null){
         beanCache.put(name, bean);
     }

     return bean;
 }

对象属性的injection

通过applyPropertyValues这个方法我们可以继承BeanFactory来实现对象属性的injection。首先通过泛型取到class里的field然后根据BeanDefinition注入对应的值。

protected void applyPropertyValues(Object bean, BeanDefinition beanDefinition) throws Exception {
    Field[] fields = bean.getClass().getDeclaredFields();
    for(Field field : fields){
        field.setAccessible(true);

        Autowired autowiredAn = field.getAnnotation(Autowired.class);
        my.annotation.Field myfieldAn = field.getAnnotation(my.annotation.Field.class);
        if (autowiredAn != null){
            field.set(bean, this.getBean(autowiredAn.name()));
        } else if (myfieldAn != null){
            Type type = field.getGenericType();
            if (type.getTypeName() == "int"){
                field.set(bean, Integer.valueOf(myfieldAn.value()));
            }else {
                field.set(bean, String.valueOf(myfieldAn.value()));
            }
        }
        else {
            for (BeanProperty beanProperty : beanDefinition.getBeanProperties()) {
                if (field.getName().equals(beanProperty.getName())) {
                    if (beanProperty.getRefBean() != null) {
                        field.set(bean, this.getBean(beanProperty.getRefBean()));
                    } else {
                        field.set(bean, beanProperty.getValue());
                    }

                    break;
                }
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值