手写--Spring--IOC

常规Spring IOC实现

Spring 依赖 :

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.3.11.RELEASE</version>
</dependency>

spring-context 会自动将 spring-core、spring-beans、spring-aop、spring-expression 这几个基础 jar 包带进来。

User:

public class User {
    private String userId;
    private String userName;

    public User() {
    }

    public User(String userId, String userName) {
        this.userId = userId;
        this.userName = userName;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId='" + userId + '\'' +
                ", userName='" + userName + '\'' +
                '}';
    }
}

user.xml

Spring–02–IOC

xml格式一定要是spring提供的标准模式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user1" class="springdemo.cy.bean.User">
       <property name="userId" value="0001"></property>
        <property name="userName" value="张三"></property>
    </bean>
    
    <bean id="user2" class="springdemo.cy.bean.User">
        <constructor-arg name="userId" value="0002"></constructor-arg>
        <constructor-arg name="userName" value="李四"></constructor-arg>
    </bean>
</beans>

测试demo:

public class test {

    public static void main(String[] args) {
       ApplicationContext appLication = new ClassPathXmlApplicationContext("user.xml");

        Object bean = appLication.getBean("user1");
        User user = (User) bean;
        System.out.println(user);

      }
}

在这里插入图片描述

用dom4j解析xml 模拟spring

在这里插入图片描述

dom4j 依赖:

dom4j相关知识: https://blog.csdn.net/weixin_48052161/article/details/115053853

<!--用于解析xml -->
<dependency>
   <groupId>dom4j</groupId>
   <artifactId>dom4j</artifactId>
   <version>1.6.1</version>
</dependency>

自定义xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="user1" class="springdemo.cy.bean.User">
        <property name="userId" value="0001"></property>
        <property name="userName" value="张三"></property>
    </bean>
    <bean id="user2" class="springdemo.cy.bean.User">
        <property name="userId" value="0002"></property>
        <property name="userName" value="李四"></property>
    </bean>
</beans>

模拟一个 ClassPathXmlApplicationContext对象

这里是通过set方法注入 还可以通过构造方法 反射注入

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ClassPathXmlApplicationContext {

    /**
     * 模拟spring管理对象的容器
     */
    Map<String,Object> map =new HashMap<>();




    public ClassPathXmlApplicationContext(String xmlPath) throws Exception {
       //模拟spring项目启动扫描
        init(xmlPath);
    }

    /**
     * 获取Bean对象
     * @param xmlPath
     * @throws Exception
     */
    public void init(String xmlPath) throws Exception{
        // 1.读取xml配置文件
        // 1.1创建xml解析器
        SAXReader saxReader = new SAXReader();
        // 1.2读取xml配置文件
        Document read = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(xmlPath));
        // 1.3获取xml配置文件的根节点对象(<beans></beans>)
        Element rootElement = read.getRootElement();
        //1.4获取根节点中所有的子节点对象,也就是所有bean对象(<bean></bean>)
        List<Element> beanElements = rootElement.elements();
        Object obj = null;
        for (Element beanElement : beanElements) {
            // 2.使用beanId查找bean配置,并获取配置文件中class的地址(为了与参数beanId区分开,我们命名为beanElementId)
            //2.1使用beanId查找bean配置
            String beanElementId = beanElement.attributeValue("id");
            // 2.2获取bean对应的Class地址
            String beanClassPath = beanElement.attributeValue("class");
            // 3.使用反射实例化对象
            // 3.1获取Class对象
            Class<?> cls = Class.forName(beanClassPath);
            // 3.2实例化对象
            obj = cls.newInstance();
            // 4.获取属性配置,使用反射技术进行赋值
            // 4.1获取所有属性
            List<Element> fieldElements = beanElement.elements();
            for (Element fieldElement : fieldElements) {
                String name = fieldElement.attributeValue("name");
                String value = fieldElement.attributeValue("value");
                // 4.2使用反射api为私有属性赋值
                Field declaredField = cls.getDeclaredField(name);
                //忽略访问权限修饰符的安全检查,又称为暴力反射
                declaredField.setAccessible(true);
                declaredField.set(obj, value);
            }

            //生成的bean对象放入map容器
            map.put(beanElementId,obj);
        }
    }

    //从map提取相应的bean对象
    public Object getBean(String name){
        return  map.get(name);
    }
}

测试demo:

public class SpringIOCDemo {

    public static void main(String[] args) throws Exception {
        //读取User的XML配置文件
        ClassPathXmlApplicationContext appLication = new ClassPathXmlApplicationContext("user01.xml");
        //获取User的Bean对象
        Object bean = appLication.getBean("user1");
        User user = (User) bean;
        System.out.println(user);
    }

}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值