您的位置:首页 > 编程语言 > Java开发

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

2015-08-30 19:54 453 查看
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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: