Spring 原理:IOC的概念
2013-10-11 16:52
387 查看
本文源码:spring原理 备用下载:spring原理
我们先来回顾一下,在没有使用spring的时候,后台业务是怎么操作的:
一,首先要有一个model(或者称为domain)类,用来存放bean
User.java
二:dao操作层,是用来和数据库打交道,执行具体的增删查改
1、dao接口:之所以使用接口是为了跨平台,当你需要oracle的数据库,就按照oracle的要求实现这个dao接口,当你需要mysql数据库就实现mySQL的接口
2、daoImpl实现:按照数据库的不同进行不同的具体实现
三:service业务层,用来处理繁杂的业务关系
1、service接口:这里接口是为了对比一般实现方法和使用类似spring注入方法的区别
四:测试
结果:
下面我们来看看使用配置文件的方式实现上面的功能:
一:注入dao的service实现
二:定义一个工厂接口BeanFactory,可以通过名字取出对应的UserDaoImpl
四:测试
上面只是自动注入了dao,service还是需要手动实例化,下面我们将sercie也放入容器:
一:service实现
二:工厂实现
三:修改beans.xml
四:测试
一般使用ApplicationContext,替换BeanFactory
可以看出,使用注入的方式,只需要改变配置文件就可以更改dao的实现,这样灵活性大大提高。
我们先来回顾一下,在没有使用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的实现,这样灵活性大大提高。
相关文章推荐
- Spring之Spring IOC(概念、原理、实践)
- Spring 概念及特点 Spring下载地址 控制反转IoC实现原理
- 解读Spring IOC和AOP原理
- spring ioc原理
- 【Spring】Spring的IOC(控制反转)/DI(依赖注入)原理(三):Spring启动加载配置文件源码分析
- Spring IOC、DI、AOP原理和实现
- Spring 原理学习-----IoC容器初始化(1)
- Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理
- Spring IOC和DI原理讲解并制作LazyCoder版的Spring (一)
- Spring IOC设计原理解析
- Spring的IOC原理
- Spring的IOC原理[通俗解释一下]
- spring IOC原理
- Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原
- spring IOC AOP原理
- Spring(1)Ioc和Aop底层原理
- 反射 实现工厂模式 和 spring IOC 实现原理
- spring ioc原理 和 java反射 体会
- java框架篇---spring IOC 实现原理
- 番外 01:Spring IoC 实现原理简析,Java的反射机制,通过类名创建对象