模拟Spring IOC DI

项目总览

公共代码

User.java

package com.itlwc.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;
	}
}

UserDao.java

package com.itlwc.dao;
import com.itlwc.model.User;
public interface UserDao {
	// Dao层增加用户方法
	public void save(User user);
}

UserDaoImpl.java

package com.itlwc.dao.impl;
import com.itlwc.dao.UserDao;
import com.itlwc.model.User;
public class UserDaoImpl implements UserDao {
	// Dao层增加用户方法
	public void save(User user) {
		System.out.println("调用了UserDaoImpl");
	}
}

UserService.java

package com.itlwc.service;
import com.itlwc.model.User;
public interface UserService {
	// Service层增加用户方法
	public void add(User user);
}

UserSerivceImpl.java

package com.itlwc.service.impl;
import com.itlwc.dao.UserDao;
import com.itlwc.model.User;
import com.itlwc.service.UserService;
public class UserServiceImpl implements UserService {
	// private UserDao userDao =new UserDaoImpl();
	// 这里不需要new了,交给了容器来new
	private UserDao userDao;
	public UserDao getUserDao() {
		return userDao;
	}
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	// Service层增加用户方法
	public void add(User user) {
		this.userDao.save(user);
	}
}

BeanFactory.java

package com.itlwc.spring;

public interface BeanFactory {
	// bean工厂
	public Object getBean(String name);
}

模拟IOC

控制反转
A类调用B类,原本是A类控制B类的实例化,转交给了容器来控制,
	这里发生了控制权的转移称为控制反转

beans

<beans>
	<bean id="userDao" class="com.itlwc.dao.impl.UserDaoImpl" />
</beans>

ClassPathXmlApplicationContext

package com.itlwc.spring;

import java.io.InputStream;
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 {
	// 容器
	private Map<String, Object> beans = new HashMap<String, Object>();

	// 根据name获取bean
	public Object getBean(String name) {
		return beans.get(name);
	}

	// 解析配置文件,放入容器
	public ClassPathXmlApplicationContext() {
		try {
			SAXBuilder sb = new SAXBuilder();
			// 读取配置文件
			InputStream in = this.getClass().getClassLoader()
					.getResourceAsStream("beans.xml");
			Document document = sb.build(in);
			// 获取根元素
			Element root = document.getRootElement();
			// 获取根元素的子元素
			List<Element> list = root.getChildren();
			for (int i = 0; i < list.size(); i++) {
				Element element = list.get(i);
				String id = element.getAttributeValue("id");
				String clazz = element.getAttributeValue("class");
				System.out.println(id + " : " + clazz);
				// 利用反射,获取Class对象,创建实例
				Object obj = Class.forName(clazz).newInstance();
				beans.put(id, obj);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

UserServiceTest

package com.itlwc.service;
import org.junit.Test;
import com.itlwc.dao.UserDao;
import com.itlwc.model.User;
import com.itlwc.service.impl.UserServiceImpl;
import com.itlwc.spring.BeanFactory;
import com.itlwc.spring.ClassPathXmlApplicationContext;
public class UserServiceTest {
	@Test
	public void testAdd() {
		// 获取工厂,从工厂中获取UserDao实例
		BeanFactory factory = new ClassPathXmlApplicationContext();
		UserDao userDao = (UserDao) factory.getBean("userDao");

		// 赋值
		UserServiceImpl service = new UserServiceImpl();
		service.setUserDao(userDao);

		// 调用增加用户方法
		User user = new User();
		service.add(user);
	}
}

打印结果

userDao : com.itlwc.dao.impl.UserDaoImpl
调用了UserDaoImpl

模拟DI

依赖注入,也叫装配
A类需要B类时,容器会自动将B类注入到A类中称为依赖注入

beans

<beans>
	<bean id="userDao" class="com.itlwc.dao.impl.UserDaoImpl" />
	<bean id="userService" class="com.itlwc.service.impl.UserServiceImpl">
		<!-- 装配 -->
		<property name="userDao" bean="userDao" />
	</bean>
</beans>

ClassPathXmlApplicationContext

package com.itlwc.spring;

import java.io.InputStream;
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 {
	// 容器
	private Map<String, Object> beans = new HashMap<String, Object>();

	// 根据name获取bean
	public Object getBean(String name) {
		return beans.get(name);
	}

	// 解析配置文件,放入容器
	public ClassPathXmlApplicationContext() {
		try {
			SAXBuilder sb = new SAXBuilder();
			// 读取配置文件
			InputStream in = this.getClass().getClassLoader()
					.getResourceAsStream("beans.xml");
			Document document = sb.build(in);
			// 获取根元素
			Element root = document.getRootElement();
			// 获取根元素的子元素
			List<Element> list = root.getChildren();
			for (int i = 0; i < list.size(); i++) {
				Element element = list.get(i);
				String id = element.getAttributeValue("id");
				String clazz = element.getAttributeValue("class");
				System.out.println(id + " : " + clazz);
				// 利用反射,获取Class对象,创建实例
				Object obj = Class.forName(clazz).newInstance();
				beans.put(id, obj);

				// 遍历属性
				List<Element> listChildren = element.getChildren();
				for (Element propertyElement : listChildren) {
					String name = propertyElement.getAttributeValue("name");
					String bean = propertyElement.getAttributeValue("bean");
					System.out.println(" name:" + name);
					System.out.println(" bean:" + bean);
					Object beanObject = beans.get(bean);
					System.out.println(beanObject);
					String methodName = "set"
							+ name.substring(0, 1).toUpperCase()
							+ name.substring(1);
					System.out.println(" method name = " + methodName);

					// 获取运行时的Class对象
					Class<?> runClazz = obj.getClass();
					/*
					 * 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法 第一个参数方法的名称
					 * 第二个参数方法的参数类型
					 */
					Method m = runClazz.getMethod(methodName, beanObject
							.getClass().getInterfaces()[0]);
					// 调用方法(注入)
					m.invoke(obj, beanObject);
					System.out.println("调用方法成功!!!");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

UserServiceTest

package com.itlwc.service;
import org.junit.Test;
import com.itlwc.model.User;
import com.itlwc.spring.BeanFactory;
import com.itlwc.spring.ClassPathXmlApplicationContext;
public class UserServiceTest {
	@Test
	public void testAdd() {
		// 获取工厂,从工厂中获取UserDao实例
		BeanFactory factory = new ClassPathXmlApplicationContext();
		UserService service= (UserService)factory.getBean("userService");
		
		// 调用增加用户方法 
		User user = new User();
		service.add(user);
	}
}

打印结果

userDao : com.itlwc.dao.impl.UserDaoImpl
userService : com.itlwc.service.impl.UserServiceImpl
 name:userDao
 bean:userDao
com.itlwc.dao.impl.UserDaoImpl@ecd7e
 method name = setUserDao
调用方法成功!!!
调用了UserDaoImpl

猜你喜欢

转载自blog.csdn.net/itlwc/article/details/38678433