spring IOC的实现原理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring IOC的实现原理相关的知识,希望对你有一定的参考价值。
姓名:罗秀群 班级:软件151
IOC的意思是控件反转也就是由容器控制程序之间的关系,把控件权交给了外部容器,之前的写法,由程序代码直接操控,而现在控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。
IOC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。
下面来模拟下IOC和DI的实现原理。
1、首先定义DAO接口和接口的实现类
package com.dao; public interface PersonDAO { public void save(); }
- package com.dao.impl;
- import com.dao.PersonDAO;
- public class PersonDaoImpl implements PersonDAO {
- @Override
- public void save() {
- System.out.println("保存");
- }
- }
2、创建一个Junit测试类
package com.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.dao.PersonDAO; import com.myUtil.MyClassPathXmlApplicationContext; import com.service.PersonService; public class PersonTest { @Test public void instanceSpring1(){ /** * * spring 的实现 */ //IOC ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); PersonDAO pd = (PersonDAO) ac.getBean("personDAO"); pd.save(); //DI PersonService ps = (PersonService) ac.getBean("personService"); ps.save(); } @Test public void instanceSpring2(){ /** * 我的实现 * */ MyClassPathXmlApplicationContext mac = new MyClassPathXmlApplicationContext("beans.xml"); PersonDAO mpd = (PersonDAO) mac.getBean("personDAO"); mpd.save(); //DI PersonService ps = (PersonService) mac.getBean("personService"); ps.save(); } }
方法instanceSpring1为Spring中的实现用到ClassPathXmlApplicationContext类,要实现IOC的原理要定义自己
的MyClassPathXmlApplicationContext首先读出beans.xml中的配置信息,通过反射机制实现bean,最后注入所需要的
bean。
package com.myUtil; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class MyClassPathXmlApplicationContext { // xml所有的属性 private ArrayList<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>(); // xml中所有的bean private Map<String, Object> sigletons = new HashMap<String, Object>(); public MyClassPathXmlApplicationContext(String file) { readXml(file); instanceBeans(); instanceObject(); } /** * 注入 */ private void instanceObject() { for (BeanDefinition beanDefinition : beanDefinitions) { //判断有没有注入属性 if (beanDefinition.getProperty() != null) { Object bean = sigletons.get(beanDefinition.getId()); if (bean != null) { try { //得到被注入bean的所有的属性 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); //得到所有的注入bean属性 for(PropertyDefinition propertyDefinition:beanDefinition.getProperty()){ for(PropertyDescriptor propertyDescriptor:ps){ if(propertyDescriptor.getName().equals(propertyDefinition.getName())){ Method setter = propertyDescriptor.getWriteMethod();//获取set方法 if(setter!=null){ setter.setAccessible(true);//得到private权限 //注入属性 setter.invoke(bean, sigletons.get(propertyDefinition.getRef())); } break; } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } /** * 实例所有的bean */ private void instanceBeans() { for (int i = 0; i < beanDefinitions.size(); i++) { BeanDefinition bd = beanDefinitions.get(i); try { try { if (bd.getClassName() != null && !bd.getClassName().equals("")) sigletons.put(bd.getId(), Class.forName( bd.getClassName()).newInstance()); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 读xml * * @param file */ private void readXml(String file) { try { SAXReader reader = new SAXReader(); // 使用SAX方式解析XML URL xmlPath = this.getClass().getClassLoader().getResource(file); Document doc = reader.read(xmlPath); Element root = doc.getRootElement(); // 取得根节点 List<Element> beans = root.elements(); for (Element element : beans) { String id = element.attributeValue("id");// id; String clazz = element.attributeValue("class"); BeanDefinition bd = new BeanDefinition(id, clazz); // 读取子元素 if (element.hasContent()) { List<Element> propertys = element.elements(); for (Element property : propertys) { String name = property.attributeValue("name"); String ref = property.attributeValue("ref"); PropertyDefinition pd = new PropertyDefinition(name, ref); bd.getProperty().add(pd); } } beanDefinitions.add(bd); } } catch (Exception e) { // TODO: handle exception } } /** * 通过名字得到bean * * @param str * @return */ public Object getBean(String str) { return sigletons.get(str); } }
读取所的bean实体
package com.myUtil; import java.util.ArrayList; import java.util.List; public class BeanDefinition { private String id; private String className; private List<PropertyDefinition> property = new ArrayList<PropertyDefinition>(); public BeanDefinition(String id, String className) { super(); this.id = id; this.className = className; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public List<PropertyDefinition> getProperty() { return property; } public void setProperty(List<PropertyDefinition> property) { this.property = property; } }
注入属性实体
package com.myUtil; public class PropertyDefinition { private String name; private String ref; public PropertyDefinition(String name, String ref) { this.name = name; this.ref = ref; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRef() { return ref; } public void setRef(String ref) { this.ref = ref; } }
业务接口和实现类
package com.service; public interface PersonService { public void save(); }
package com.service.impl; import com.dao.PersonDAO; import com.service.PersonService; public class PersonServiceImpl implements PersonService{ private PersonDAO pdo; public PersonDAO getPdo() { return pdo; } public void setPdo(PersonDAO pdo) { this.pdo = pdo; } @Override public void save() { pdo.save(); } }
beans.xml配置
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
- <bean id="personDAO" class="com.dao.impl.PersonDaoImpl"></bean>
- <bean id="personService" class="com.service.impl.PersonServiceImpl">
- <property name="pdo" ref="personDAO"></property>
- </bean>
- </beans>
以上是关于spring IOC的实现原理的主要内容,如果未能解决你的问题,请参考以下文章