简单手写Spring IOC框架的实现

143 阅读1分钟

简单手写Spring IOC框架的实现

Spring IOC

SpringIOC就是把每一个bean与bean之间的关系交给第三方容器进行管理。

底层实现原理

1.读取bean的XML配置文件

2.使用beanId查找bean配置,并获取配置文件中class地址。

3.使用Java反射技术实例化对象

4.获取属性配置,使用反射技术进行赋值。

编码实现

spring.xml

<beans>
	<bean id="user1" class="cn.ybzy.demo.model.User">
		<property name="name" value="小白"></property>
		<property name="address" value="中国"></property>
	</bean>
	<bean id="user2" class="cn.ybzy.demo.model.User">
		<property name="name" value="大白"></property>
		<property name="address" value="上海"></property>
	</bean>
</beans>

使用dom4j解析XML

<dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>1.6.1</version>
</dependency>
public class ClassPathXmlApplicationContext {

    private String xmlConfigName;

    public ClassPathXmlApplicationContext(String xmlConfigName) {
        this.xmlConfigName = xmlConfigName;
    }

    /**
     * spring加载过程或者spring ioc实现原理
     *
     * @param beanId
     * @return
     * @throws Exception
     */
    public Object getBean(String beanId) throws Exception {
        //读取xml配置文件
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(xmlConfigName);
        //获取xml解析器
        SAXReader saxReader = new SAXReader();
        //解析器读取配置文件
        Document read = saxReader.read(inputStream);
        //获取跟节点对象
        Element rootElement = read.getRootElement();
        List<Element> elements = rootElement.elements();
        Object obj = null;
        for (Element sonEle : elements) {
            //获取每个bean的名称
            String oneBeanId = sonEle.attributeValue("id");
            if (!beanId.equals(oneBeanId)) {
                continue;
            }
            //获取每个bean的class地址
            String beanClassPath = sonEle.attributeValue("class");
            //拿到class地址 进行反射实例化对象
            Class<?> forName = Class.forName(beanClassPath);
            obj = forName.newInstance();
            //拿到成员属性使
            List<Element> propertys = sonEle.elements();
            for (Element element : propertys) {
                String name = element.attributeValue("name");
                String value = element.attributeValue("value");
                //使用反射api为私有属性赋值
                Field declaredField = forName.getDeclaredField(name);
                //允许设置私有成员赋值
                declaredField.setAccessible(true);
                declaredField.set(obj, value);
            }

        }
        return obj;
    }

    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext appLication = new ClassPathXmlApplicationContext("user.xml");
        Object bean = appLication.getBean("user1");
        User user = (User) bean;
        System.out.println(user.getName() + "----" + user.getAddress());
    }
}