SpringIOC底层原理

实体类:

User.java

package com.foreknow.model;

public class User {
    private String username;
    private String password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

DAO层:

UserDao.java

package com.foreknow.dao;

import com.foreknow.model.User;

public interface UserDao {
    /**
     * 添加
     * @param user
     */
    public void save(User user);
}

DAO实现类:

UserDaoImpl.java

package com.foreknow.dao.impl;

import com.foreknow.dao.UserDao;
import com.foreknow.model.User;

public class UserDaoImpl implements UserDao {
    @Override
    public void save(User user) {
        System.out.println("save........");
    }
}

Service层:

UserService.java

package com.foreknow.service;

import com.foreknow.dao.impl.UserDaoImpl;
import com.foreknow.model.User;

public interface UserService {
    /**
     * addInfo
     * @param user
     */
    public void addInfo(User user);
}

Service层实现类:

UserServiceImpl.java

package com.foreknow.service.impl;

import com.foreknow.dao.UserDao;
import com.foreknow.dao.impl.UserDaoImpl;
import com.foreknow.model.User;
import com.foreknow.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void addInfo(User user) {
        // TODO Auto-generated method stub
        userDao.save(user);
    }
}

BeanFactory.java

package com.foreknow.spring;

public interface BeanFactory {
    /**
     * 根据key获取到value
     * @param id(key)
     * @return Object
     */
    public Object getBean(String id);
}

ClassPathXmlApplicationContext.java

package com.foreknow.spring;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import com.foreknow.dao.UserDao;



public class ClassPathXmlApplicationContext implements BeanFactory {
    //创建一个工厂容器
    private Map beans = new HashMap<>();
    //使用构造器来解析beans.xml文件
    public ClassPathXmlApplicationContext() throws Exception{
        //1.创建一个解析器
        SAXBuilder saxBuilder = new SAXBuilder();
        //2.解析并读取beans.xml文件 构造Document文档对象
        Document document = saxBuilder.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));
        //3.获取到根节点
        Element element = document.getRootElement();
        //4.获取到子节点
        List list = element.getChildren("bean");
        for(int i = 0;i < list.size();i++) {
            Element e = list.get(i);
            String id = e.getAttributeValue("id");//u
            String clazz = e.getAttributeValue("class");//com.foreknow.dao.impl.UserDaoImpl
            System.out.println(id);
            System.out.println(clazz);
            //要将clazz转换为UserDaoImpl对象并将id以及对象保存到Map集合中
            Object o = Class.forName(clazz).newInstance();
            beans.put(id,o);
            //List list2 = element.getChildren("property");
            //获取到bean中的子节点的property
            for(Element propertyElement:(List)e.getChildren("property")) {
                String name = propertyElement.getAttributeValue("name");//userDao
                String bean = propertyElement.getAttributeValue("bean");//u
                //从Map中获取到UserDaoImpl对象
                Object beanObject = beans.get(bean);
                //模拟调用public void setUserDAO(UserDAO userDAO)
                String methodName = "set"+name.substring(0, 1).toUpperCase()+name.substring(1);
                System.out.println(methodName);
                //需要java中的反射机制来自动调用setUserDAO方法
                //o.getClass().getMethod获取到UserServiceImpl对象中的某一个方法setUserDAO
                //beanObject.getClass.getInterfaces()[0]获取到方法的参数UserDAO
                Method method = o.getClass().getMethod(methodName,beanObject.getClass().getInterfaces()[0] );
                //方法调用   o:UserServiceImpl对象中的setUserDAO(UserDAO userDAO)方法
                //beanObject:调用此方法时需要传入的参数 UserDAOImpl对象
                method.invoke(o,beanObject);
            }
        }
    }

    @Override
    public Object getBean(String id) {
        return beans.get(id);
    }
    
    public static void main(String[] args) {
        try {
            new ClassPathXmlApplicationContext();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Test.java

package com.foreknow.test;

import com.foreknow.dao.impl.UserDaoImpl;
import com.foreknow.model.User;
import com.foreknow.service.UserService;
import com.foreknow.service.impl.UserServiceImpl;

public class Test {
    public static void main(String[] args) {
        UserServiceImpl service = new UserServiceImpl();
        service.setUserDao(new UserDaoImpl());
        service.addInfo(new User());
    }
}

你可能感兴趣的:(SpringIOC底层原理)