??????????? 模拟了spring容器的依赖注入,其实spring内部也是通过反射机制来实现的控制反转。主要是看下spring包下的ClassPathXmlApplicationContext类的实现。?
?????????????????? private String name;
????????????????????????????? return name;
?????????????????? }
??????????????????????????????this.name = name;
?????????????????? }
?
????????? }
???????? //设计这个接口,是为了更灵活,因此不同的数据库产品,实现方式不一样
???????? //为了可扩展,把这里设计成接口
?????????public interface UserDao {
???????????????????public void save(User u);
???????? }
???????? import com.bjsxt.model.User;
????????????????????????????? System.out.println("a user is save.");
?????????????????? }
???????? import com.bjsxt.model.User;
??????? ?//这里我定义成接口类型,这样,我想用哪种数据库产品的实现
???????? //我就new哪种,比如userDao = new UserDaoImpl(),如果我想换
???????? //其它的实现,就更改下那句话就行,要是放在配置文件里,就只需更改配置文件
???????? //这就是面向接口的编程
???????? ?????????? private UserDao userDao;
??????????????????? ????????? return userDao;
?????????????????? }
??????????????????????????????this.userDao = userDao;
?????????????????? }
?????????????????? ?public void save(User u){
????????????????????????????? userDao.save(u);
?????????????????? }
???????? }
?????????????????? Object getBean(String id);
???????? }
?????????package spring;
???????? import java.lang.reflect.InvocationTargetException;
?????????import java.lang.reflect.Method;
???????? import java.util.*;
???????? import org.jdom.Element;
???????? import org.jdom.JDOMException;
???????? import org.jdom.input.SAXBuilder;
?
????????????????? ?private Map<String,Object> beans = new HashMap<String,Object>();
?
?????????????????? public ClassPathXmlApplicationContext() throws JDOMException, IOException{
???????????????????????????? SAXBuilder sb = new SAXBuilder();
???????????????????????????? Document doc = sb.build(ClassPathXmlApplicationContext.class
??????????.getClassLoader().getResourceAsStream("beans.xml"));
????????????????? ?Element root = doc.getRootElement();
???????????????????List list = root.getChildren("bean");
???????????????????for(int i=0;i<list.size();i++){
??????????????????????????????????Element element = (Element) list.get(i);
????????????????????????????????? String id = element.getAttributeValue("id");
????????????????????????????????? String clazz = element.getAttributeValue("class");
????????????????????????????????? Object o = null;
?????????????????????????????????try {
????????????????????????????????????????? ?//利用反射机制,根据完整的包名+类名,new出实例
????????????????????????????????????????????o = Class.forName(clazz).newInstance();
???????????????????????????????????? ?????? beans.put(id, o);
???????????????????????????????? } catch (ClassNotFoundException e) {
?????????????????????????????????????????? ?e.printStackTrace();
???????????????????????????????? } catch (InstantiationException e) {
?????????????????????????????????????????? ?e.printStackTrace();
???????????????????????????????? } catch (IllegalAccessException e) {
????????????????????????????????????????????e.printStackTrace();
???????????????????????????????? }
??????????????????? ?List elements = element.getChildren("property");
?????????????????????for(int j=0;j<elements.size();j++){
?????????????????????????? Element ele = (Element) elements.get(j);
???????????????????????????String name = ele.getAttributeValue("name");//userDao
?????????????????????????? String bean = ele.getAttributeValue("bean");//u
?????????????????????????? Object beanObject = beans.get(bean);//userDaoImpl instance
????????????????????????? ?//其实就相当于找方法名setUserDao;
?????????????????????????? String methodName = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
????
???????????????????????????????? //根据反射机制,执行set方法,这里,先找到方法名,
???????????????????????????????? //根据方法名和方法参数拿到method
???????????????????????????????? // 比如,public void setUserDao(UserDao userDao),这里的方法参数userDao它实现了
???????????????????????????????? //这样就完成了注入
???????????????????????????????? ?Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
???????????????????????????????? ?m.invoke(o, beanObject);
?????????????????????????? } catch (SecurityException e) {
???????????????????????????????????? ?e.printStackTrace();
?????????????????????????? } catch (NoSuchMethodException e) {
???????????????????????????????????? ?e.printStackTrace();
???????????????????????? ? } catch (IllegalArgumentException e) {
????????????????????????????????????? e.printStackTrace();
?????????????????????????? } catch (IllegalAccessException e) {
???????????????????????????????????? ?e.printStackTrace();
?????????????????????????? } catch (InvocationTargetException e) {
???????????????????????????????????? ?// TODO Auto-generated catch block
??????????????????????????????????????e.printStackTrace();
?????????????????????????? }
????
?????????????????????? ?}
?????????????????? }
???????? ??? }
?
??????????????????public Object getBean(String id) {
??
????????????????? ????????? return beans.get(id);
??????????????????}
?
??????? }
??????? <beans>
??????????????????? <bean id="u" class="com.bjsxt.dao.impl.UserDaoImpl" />
??????????????????? <bean id="userService" class="com.bjsxt.service.UserService" >
??????????????????? <property name="userDao" bean="u"/>
??????????????????? </bean>
?
??????? </beans>
?
????????测试代码如下:
?
??????? package com.bjsxt.service;
?
??????? import static org.junit.Assert.*;
??????? import java.io.IOException;
??????? import org.jdom.JDOMException;
??????? import org.junit.Test;
??????? import spring.ClassPathXmlApplicationContext;
??????? import com.bjsxt.model.User;
?
??????? public class UserServiceTest {
????????????????? //junit4的特点就是不用显示继承TestCase,只要在那个方法前加上注解@Test
??????????????????public void testSave() {
????????????????????????????ClassPathXmlApplicationContext context = null;
????????????????????????????try {
???????????????????????????????? ?context = new ClassPathXmlApplicationContext();
?????????????????????????? ?} catch (JDOMException e) {
??????????????????????????????????????? e.printStackTrace();
??????????????????????????? } catch (IOException e) {
?????????????????????????????????????? ?e.printStackTrace();
?????????????????????????? ?}
??????????????????????????? ?UserService us = (UserService) context.getBean("userService");
???????????????????????????? User u = new User();
??????????????????????????? ?us.save(u);
??????????????????}
????????? }