手写SpringIoc底层实现代码,基于反射机制

1:什么是springIoc?

就是每个bean与bean的关系交给Spring第三方容器来管理。

2:如何实现?

1.利用传入的参数获取xml文件的流,并且利用dom4j解析成Document对象

2.对于Document对象获取根元素对象<beans>后对下面的<bean>标签进行遍历,判断是否有符合的id.

3.如果找到对应的id,相当于找到了一个Element元素,开始创建对象,先获取class属性,根据属性值利用反射建立对象.

4.遍历<bean>标签下的property标签,并对属性赋值.注意,需要单独处理int,float类型的属性.因为在xml配置中这些属性都是以字符串的形式来配置的,因此需要额外处理.

5.如果属性property标签有ref属性,说明某个属性的值是一个对象,那么根据id(ref属性的值)去获取ref对应的对象,再给属性赋值.

6.返回建立的对象,如果没有对应的id,或者<beans>下没有子标签都会返回null

 

3:代码如下

user实体类

public class User {
    private Integer userId;
    private String userName;
    public Integer getUserId() {
        return userId;
    }
    public void setUserId(Integer userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    
}
 

application.xml配置

<beans>

    <bean id="user1" class="springIoc.User">
        <property name="userId" value="1"></property>
        <property name="userName" value="张三"></property>
    </bean>
    <bean id="user2" class="springIoc.User">
        <property name="userId" value="2"></property>
        <property name="userName" value="张三"></property>
    </bean>


</beans>   

public class ClassPathXmlApplication {
    private String xmlPath;
    
   public ClassPathXmlApplication(String xmlPath){
       this.xmlPath=xmlPath;
   }
   
    public Object getBeans(String beanId) throws Exception{
           //如何实现springIoc的底层原理
        /**
         * 1:解析xml配置文件
         * 2:读取bean配置获取class属性路径
         * 3:根据反射原理对class路径进行实例化,为私有属性赋值。

         * @return
         */
       SAXReader reader=     new SAXReader();
       Document document=         reader.read(this.getClass().getClassLoader().getResourceAsStream(xmlPath));
       Element beansElement=    document.getRootElement();
       List<Element> beanList=  beansElement.elements();
       Object obj=null;
       for (Element beanElement : beanList) {
           String beanId1=   beanElement.attributeValue("id");
           if(!beanId1.equals(beanId)){
               continue;
           }
            //获取bean中的class
           String classPath=   beanElement.attributeValue("class");
           //进行实例化拿到对象
           Class forName=   Class.forName(classPath);
           obj=forName.newInstance();
             List<Element> beanSonElement=  beanElement.elements();
             for (Element sonElement : beanSonElement) {
              String name=  sonElement.attributeValue("name");
              String value=  sonElement.attributeValue("value");

            //使用反射未私有属性赋值
              Field field=forName.getDeclaredField(name);
              field.setAccessible(true);
              System.out.println(field.getType());
              if(field.getType().toString().equals("class java.lang.Integer")){//对非String类型的特殊处理
                  field.set(obj, Integer.parseInt(value));
              }else{
                  field.set(obj, value);
              }
             }
       }
           return obj;
       }
    
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplication classPath=new ClassPathXmlApplication("applicationContext.xml");
        User user=   (User) classPath.getBeans("user1");
        System.out.println(user.getUserName());张三
    }
}

 

转载于:https://my.oschina.net/lsm97103/blog/1579722

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值