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

Spring 原理:IOC的概念

2013-10-11 16:52 387 查看
本文源码:spring原理 备用下载:spring原理

我们先来回顾一下,在没有使用spring的时候,后台业务是怎么操作的:

一,首先要有一个model(或者称为domain)类,用来存放bean

User.java

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


二:dao操作层,是用来和数据库打交道,执行具体的增删查改

1、dao接口:之所以使用接口是为了跨平台,当你需要oracle的数据库,就按照oracle的要求实现这个dao接口,当你需要mysql数据库就实现mySQL的接口

package com.haizhu.dao;

import com.haizhu.model.User;

public interface UserDao {
public void addUser(User u);
}


2、daoImpl实现:按照数据库的不同进行不同的具体实现

package com.haizhu.dao.impl;

import com.haizhu.dao.UserDao;
import com.haizhu.model.User;

public class UserDaoImpl implements UserDao {
@Override
public void addUser(User u) {
System.out.println("A user saved !");
}
}
注:为了简化范例,这里没有执行数据库的操作,只是将数据输出到控制台。

三:service业务层,用来处理繁杂的业务关系

1、service接口:这里接口是为了对比一般实现方法和使用类似spring注入方法的区别

package com.haizhu.service;

import com.haizhu.model.User;

public interface UserService {
public void addUser(User u);
}
2、serviceImpl一般实现:没有使用spring的时候,UserDao需要手动初始化

package com.haizhu.service.impl;

import com.haizhu.dao.UserDao;
import com.haizhu.dao.impl.UserDaoImpl;
import com.haizhu.model.User;
import com.haizhu.service.UserService;

// 当使用原始的方法的时候,这么做,来进行初始化
public class SimpleUserServiceImpl implements UserService {
// 这里UserDao 需要手动实例化,与spring的主要区别就在这里
private UserDao newUserDao = new UserDaoImpl();

public void addUser(User u){
newUserDao.addUser(u);
}
}


四:测试

package com.haizhu.service.impl;

import org.junit.Test;

import com.haizhu.model.User;
import com.haizhu.service.UserService;

public class SimpleUserServiceImplTest {

@Test
public void test() {
// 实例化一个 UserService,具体的实现是SimpleUserServiceImpl
UserService service = new SimpleUserServiceImpl();
// 实际项目中,这个 user 是从页面传递过来的,通过struts在action中进行接收
User u = new User();
// 调用dao层的具体操作方法,现实数据库操作
service.addUser(u);
}
}


结果:

A user saved !


下面我们来看看使用配置文件的方式实现上面的功能:

一:注入dao的service实现

package com.haizhu.service.impl;

import com.haizhu.dao.UserDao;
import com.haizhu.model.User;
import com.haizhu.service.UserService;
import com.haizhu.spring.BeanFactory;
import com.haizhu.spring.ClassPathXmlApplicationContext;
// 当使用spring的时候,交给xml配置文件来初始化
public class DIDaoUserServiceImpl implements UserService {
BeanFactory factory = new ClassPathXmlApplicationContext();
private UserDao springUserDao = (UserDao) factory.getBean("u");;
public void addUser(User u) {
springUserDao.addUser(u);
}
}


二:定义一个工厂接口BeanFactory,可以通过名字取出对应的UserDaoImpl

package com.haizhu.spring;

public interface BeanFactory {
public Object getBean(String name);
}
工厂的具体实现

package com.haizhu.spring;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

public class ClassPathXmlApplicationContext implements BeanFactory{

// 作为存储所有 bean 的容器
private Map<String,Object> beans = new HashMap<String,Object>();
// 构造方法
public ClassPathXmlApplicationContext(){
try {
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build(this.getClass().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");
System.out.println(id+":"+clazz);
Object o= Class.forName(clazz).newInstance();
// 将这个bean放到beans容器中
beans.put(id, o);;
}
}catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} //构造文档对象
}

public Object getBean(String name) {
// 根据名字从beans容器中取出这个bean
return beans.get(name);
}

}
三:配置文件 beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="u" class="com.haizhu.dao.impl.UserDaoImpl"></bean>
</beans>


四:测试

package com.haizhu.service.impl;

import org.junit.Test;

import com.haizhu.model.User;
import com.haizhu.service.UserService;

public class DIDaoUserServiceImplTest {
@Test
public void test() {
UserService service = new DIDaoUserServiceImpl();
User u = new User();
service.addUser(u);
}
}


上面只是自动注入了dao,service还是需要手动实例化,下面我们将sercie也放入容器:

一:service实现

package com.haizhu.service.impl;

import com.haizhu.dao.UserDao;
import com.haizhu.model.User;
import com.haizhu.service.UserService;
// 当使用spring的时候,交给xml配置文件来初始化
public class SpringUserServiceImpl implements UserService {
private UserDao userDao;

public void addUser(User u) {
userDao.addUser(u);
}

public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}

}


二:工厂实现

package com.haizhu.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 {

private Map<String, Object> beans = new HashMap<String, Object>();

// IOC Inverse of Control DI Dependency Injection
public ClassPathXmlApplicationContext() {
try {
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);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

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

}


三:修改beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="u" class="com.haizhu.dao.impl.UserDaoImpl"></bean>
<bean id="service" class="com.haizhu.service.impl.SpringUserServiceImpl" >
<property name="userDao" bean="u"/>
</bean>
</beans>


四:测试

package com.haizhu.service.impl;

import org.junit.Test;

import com.haizhu.model.User;
import com.haizhu.service.UserService;
import com.haizhu.spring.BeanFactory;
import com.haizhu.spring.ClassPathXmlApplicationContext;

public class SpringUserServiceImplTest {
@Test
public void test() {
// 取出容器中的service
BeanFactory applicationContext = new ClassPathXmlApplicationContext();
UserService service = (UserService) applicationContext.getBean("service");
User u = new User();
service.addUser(u);
}
}

一般使用ApplicationContext,替换BeanFactory

package com.haizhu.service.impl;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.haizhu.model.User;
import com.haizhu.service.UserService;

public class UserServiceImplTest extends UserServiceImpl {

@Test
public void test() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserService service = (UserService)ctx.getBean("service");
User u = new User();
service.addUser(u);
}
}


可以看出,使用注入的方式,只需要改变配置文件就可以更改dao的实现,这样灵活性大大提高。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: