Spring笔记(第一弹:简单模拟Spring IOC)

来源:互联网 发布:例外女装淘宝 编辑:程序博客网 时间:2024/06/06 17:15

Spring博大精深,功能非常多。我们这里简单的模拟一下spring的IOC。

先把model,dao,service写出来,写一个最简单的为例。
在model包下定义一个User:

package com.hello.model;public class User {    private String userId;    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;    }    private String userName;}

在dao包下定义一个UserDAO:

package com.hello.dao;import com.hello.model.User;public interface UserDAO {    public void add(User user);}

在dao.impl包下定义一个UserDAOImpl:

package com.hello.dao.impl;import com.hello.dao.UserDAO;import com.hello.model.User;public class UserDAOImpl implements UserDAO {    @Override    public void add(User user) {        System.out.println("A user added!");    }}

在service包下定义一个UserService:

package com.hello.service;import com.hello.model.User;public interface UserService {    public void add(User user);}

在service.impl包下定义一个UserServiceImpl:

package com.hello.service.impl;import com.hello.dao.UserDAO;import com.hello.model.User;import com.hello.service.UserService;public class UserServiceImpl implements UserService {    private UserDAO userDAO;    public UserDAO getUserDAO() {        return userDAO;    }    public void setUserDAO(UserDAO userDAO) {        this.userDAO = userDAO;    }    @Override    public void add(User user) {        userDAO.add(user);    }}

注意这个UserServiceImpl里的userDAO属性要提供好get,set方法,因为我们后面要通过反射机制,把dao给set进来。

下面就是重头戏了,我们要模拟spring,自然要写一个ApplicationContext.xml:

<beans>    <bean id="userDAOImpl" class="com.hello.dao.impl.UserDAOImpl" />    <bean id="userServiceImpl" class="com.hello.service.impl.UserServiceImpl">        <property name="userDAO" ref="userDAOImpl"></property>    </bean></beans>

再模拟一个BeanFactory:

package com.hello.spring;public interface BeanFactory {    public Object getBean(String name);}

再来一个ClassPathXmlApplicationContext,实现BeanFactory接口:

package com.hello.spring;import java.lang.reflect.Method;import java.util.HashMap;import java.util.List;import java.util.Map;import org.jdom2.Document;import org.jdom2.Element;import org.jdom2.input.SAXBuilder;public class ClassPathXmlApplicationContext implements BeanFactory {    // 从配置文件里解析出来的所有的bean都会放在这个容器里    private Map<String, Object> beans = new HashMap<String, Object>();    public ClassPathXmlApplicationContext() throws Exception {        SAXBuilder sb = new SAXBuilder();        // 读取配置文件        Document document = sb.build(this.getClass().getClassLoader().getResourceAsStream("ApplicationContext.xml"));        // 获取跟节点,即beans节点        Element rootElement = document.getRootElement();        // 获取所有的bean节点        List<Element> elementList = rootElement.getChildren("bean");        // 遍历每一个bean节点,把所有的bean都放到beans容器中,并对每一个bean进行自动装配        for (int i = 0; i < elementList.size(); i++) {            // 读取bean节点的id和class属性            Element element = elementList.get(i);            String id = element.getAttributeValue("id");            String clazz = element.getAttributeValue("class");            // 通过反射获取这个class对应的实例            Object o = Class.forName(clazz).newInstance();            // 放入到beans容器中            beans.put(id, o);            // 遍历这个bean中所有的property节点            for (Element propertyElement : element.getChildren("property")) {                // 读取property节点的name属性,这个name就是要注射的bean的名字                String name = propertyElement.getAttributeValue("name");                // 读取property节点的ref属性,这个ref就是在beans容器中的bean的名字                String ref = propertyElement.getAttributeValue("ref");                // 从beans容器中获取到这个ref所对应的bean                Object refBeanObject = beans.get(ref);                // 根据name,构造出set方法的方法名                String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);                // 根据方法名和参数获取到set方法                Method m = o.getClass().getMethod(methodName, refBeanObject.getClass().getInterfaces()[0]);                // 调用set方法,进行注射。这样就实现了自动装配                m.invoke(o, refBeanObject);            }        }    }    @Override    public Object getBean(String name) {        return beans.get(name);    }}

以上已经模拟完成,我们测试一下:

package com.hello.spring;import com.hello.model.User;import com.hello.service.UserService;public class test {    public static void main(String[] args) throws Exception {        BeanFactory beanFactory = new ClassPathXmlApplicationContext();        UserService userService = (UserService) beanFactory.getBean("userServiceImpl");        userService.add(new User());    }}

运行一下,可以看到控制台输出:

A user added!

到此,我们已经成功的模拟了一个最简单的spring。

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 离职怎么办档案放在人才市场 人才房住了6年后怎么办 医保辞职后断了怎么办 社保断了生育险怎么办 深圳小产权房水电费纠纷怎么办 有公租房的再婚怎么办 廉租房被没收了怎么办 商铺到期房东不续租怎么办 天津集体户口买不起房怎么办 房东不想续租了怎么办 唯一住房卖掉后户口怎么办 杭州唯一住房卖掉后户口怎么办 唯一一套住房卖掉户口怎么办 房租押金条丢了怎么办 二建证书跟毕业证丢失怎么办 住宅房到70年怎么办 护照号变了机票怎么办 苹果se指纹坏了怎么办 月经推迟怎么办才能快点来 车载支架不粘了怎么办 otpc平板电脑无法开机怎么办 手表表轴掉了怎么办 鸡肉放冰箱臭了怎么办 鸡胸肉熟了腥怎么办 梦幻西游手游手机号换了怎么办 ppt做一半卡住了怎么办 吃了发霉的蚝油怎么办 蛋皮干燥起皮怎么办 wps卡顿资料没保存怎么办 手指受伤肉掉了怎么办 手机被wifi禁了怎么办 母乳一边是咸的怎么办 tcl电视蓝频了怎么办 长虹电视蓝频了怎么办 电视突然蓝频了怎么办 海信电视蓝频了怎么办 连网电视蓝频了怎么办 英雄联盟画面卡顿怎么办 长残了怎么办原来很帅 被吓到了怎么办没精神 宝宝吓着怎么办最有效