Henry Sun

没有所谓的偶然,一切皆是因果

博客园 首页 新随笔 管理

  Spring简单的说就是作为控制反转的容器,看这篇文章前需要先搞懂“控制反转和依赖注入“这个设计模式

  我们先来模拟Spring,实现用户添加的功能,新建WEB项目”Spring_0100_AbstractOrientedProgramming“,新建包”com.bjsxt.model“,创建一个User实体

package com.bjsxt.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;
    }
}
User实体

  新建包”com.bjsxt.dao“,创建操作用户的接口"UserDAO",针对接口编程的好处是,接口的实现类可以无限拓展

package com.bjsxt.dao;
import com.bjsxt.model.User;


public interface UserDAO {
    public void save(User user);
}
UserDAO

  新建包”com.bjsxt.dao.impl“,创建一个接口的实现类”UserDAOImpl“,用一个输出模拟保存成功

package com.bjsxt.dao.impl;

import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User;


public class UserDAOImpl implements UserDAO {

    public void save(User user) {
        //Hibernate
        //JDBC
        //XML
        //NetWork
        System.out.println("user saved!");
    }

}
UserDAOImpl

  新建包”com.bjsxt.service“,新建类”UserService“,有一个”UserDAO“类型的属性,并且有对应的getter和setter方法,还有一个add方法调用UserDAO的save方法实现用户添加

package com.bjsxt.service;
import com.bjsxt.dao.UserDAO;
import com.bjsxt.dao.impl.UserDAOImpl;
import com.bjsxt.model.User;



public class UserService {
    private UserDAO userDAO;
    
    public void add(User user) {
        userDAO.save(user);
    }
    public UserDAO getUserDAO() {
        return userDAO; 
    }
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }
}
UserService

 

  按照传统方式,我们应该是在UserService中自己实例化UserDAO属性,但是现在这一切都交给Spring来完成,它会帮我们实例化,并且通过UserServcie的setter方法给UserDAO属性赋值。我们需要将对象写到配置文件里,然后Spring会读取配置文件,在运行时动态生成对象供我们调用

<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>
保存对象的XML文件

  新建包”com.bjsxt.spring“,创建模拟Spring的接口”BeanFactory“和"ClassPathXmlApplicationContext"

package com.bjsxt.spring;

public interface BeanFactory {
    public Object getBean(String id);
}
BeanFactory
package com.bjsxt.spring;


import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

public class ClassPathXmlApplicationContext implements BeanFactory {
    
    private Map<String , Object> beans = new HashMap<String, Object>();
    
    
    //IOC Inverse of Control DI Dependency Injection
    public ClassPathXmlApplicationContext() throws Exception {
        SAXBuilder sb=new SAXBuilder();
        
        Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); //�����ĵ�����
        Element root=doc.getRootElement(); //��ȡ��Ԫ��HD
        List list=root.getChildren("bean");//ȡ����Ϊdisk������Ԫ��
        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 = Class.forName(clazz).newInstance();
           System.out.println(id);
           System.out.println(clazz);
           beans.put(id, o);
           
           for(Element propertyElement : (List<Element>)element.getChildren("property")) {
               String name = propertyElement.getAttributeValue("name"); //userDAO
               String bean = propertyElement.getAttributeValue("bean"); //u
               Object beanObject = beans.get(bean);//UserDAOImpl instance
               
               String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
               System.out.println("method name = " + methodName);
               
               Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
               m.invoke(o, beanObject);
           }
           
           
        }  
      
    }



    public Object getBean(String id) {
        return beans.get(id);
    }

}
ClassPathXmlApplicationContext

  接下来用JUnit做单元测试,新建源文件夹"Test"存放测试代码,新建包”com.bjsxt.service“,创建测试类”UserServiceTest“

package com.bjsxt.service;
import org.junit.Test;

import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User;
import com.bjsxt.spring.BeanFactory;
import com.bjsxt.spring.ClassPathXmlApplicationContext;


public class UserServiceTest {

    @Test
    public void testAdd() throws Exception {
        BeanFactory applicationContext = new ClassPathXmlApplicationContext();
        UserService service = (UserService)applicationContext.getBean("userService");
        User u = new User();
        u.setUsername("zhangsan");
        u.setPassword("zhangsan");
        service.add(u);
    }

}
测试类

  运行,效果如图

  看到了吗,UserService中的add方法需要调用UserDAO的实例方法save,但是并没有实例化UserDAO属性,而是交给了Spring来完成

  具体项目文件如图

  

posted on 2015-06-22 19:47  Sam Flynn  阅读(356)  评论(0编辑  收藏  举报