Spring笔记——模拟spring的bean管理原理以及依赖注入原理
来源:互联网 发布:苹果签名软件 编辑:程序博客网 时间:2024/05/01 19:53
有点时间,正好看了spring的教程,就试着写点东西模拟了下spring的这个简单过程!
强力推荐传智播客,里面的视频资源很nice!
搭建spring环境,通过junit测试效果!
service包下的几个类,都比较简单 ,
PersonServiceDaoImpl:
package com.silence.service.bean;import com.silence.service.PersonServiceDao;public class PersonServiceDaoImpl implements PersonServiceDao {public void add() {System.out.println("dao 方法");}}
PersonServiceImpl:
package com.silence.service.bean;import com.silence.service.PersonService;import com.silence.service.PersonServiceDao;public class PersonServiceImpl implements PersonService {/* (non-Javadoc) * @see com.silence.service.bean.PersonService#save() */private PersonServiceDao personDao;private String name;public PersonServiceImpl(){//System.out.println("shilihua !");}public void save(){System.out.println("name="+name);personDao.add();}public void setPersonDao(PersonServiceDao personDao) {this.personDao = personDao;}public PersonServiceDao getPersonDao() {return personDao;}public void setName(String name) {this.name = name;}public String getName() {return name;}}PersonService和PersonServiceDao:
package com.silence.service;public interface PersonService {public void save();}
package com.silence.service;public interface PersonServiceDao {public void add();}
Bean:
package com.silence.util;import java.util.List;/** * 装载Beans.xml文件下的Bean的描述 * @author silence * */public class Bean {private String id;private String className;private List<Property> propertys;public Bean(String id, String className ,List<Property> propertys) {this.setId(id);this.setClassName(className);this.setPropertys(propertys);}public void setClassName(String className) {this.className = className;}public String getClassName() {return className;}public void setId(String id) {this.id = id;}public String getId() {return id;}public void setPropertys(List<Property> propertys) {this.propertys = propertys;}public List<Property> getPropertys() {return propertys;}}Property:
package com.silence.util;/** * 用来装载Beans.xml下的property描述 * @author silence * */public class Property {private String name;private String ref;private String value ;public void setName(String name) {this.name = name;}public String getName() {return name;}public void setRef(String ref) {this.ref = ref;}public String getRef() {return ref;}public Property(String name, String ref , String value) {this.name = name;this.ref = ref;this.value = value;}public void setValue(String value) {this.value = value;}public String getValue() {return value;}}MyClassPathXmlApplicationContext:
package com.silence.util;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.io.File;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.apache.commons.beanutils.ConvertUtils;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.XPath;import org.dom4j.io.SAXReader;/** * 模拟一个微量的spring容器 * @author silence * */public class MyClassPathXmlApplicationContext {private List<Bean> beans;private List<Property> propertys;private Map<String,Object> singleton; //默认情况的下的单例模式!public MyClassPathXmlApplicationContext(String fileName){beans = new ArrayList<Bean>();singleton = new HashMap<String, Object>();//propertys = new ArrayList<Property>();this.readXML(fileName);this.instanceBean();this.injection();}/** * setter注入 * 实现bean的注入 */private void injection() {for(Bean bean : beans){Object temp = singleton.get(bean.getId());if(temp != null && bean.getPropertys() != null){ //对象为null或者属性个数为0的时候不进行注入操作try{//获取对象的属性描述,返回一个属性描述的数组PropertyDescriptor[] ps = Introspector.getBeanInfo(temp.getClass()).getPropertyDescriptors(); for(Property property:bean.getPropertys()){for(PropertyDescriptor p: ps){if(property.getName().equals(p.getName())){Method setter = p.getWriteMethod();if(setter != null){Object value = null;if(property.getRef() != null && !"".equals(property.getRef())){value = singleton.get(property.getRef());}else{//apache的提供的工具类,可以将String转化成已知的基本类型value = ConvertUtils.convert(property.getValue(), p.getPropertyType());}setter.setAccessible(true);setter.invoke(temp, value);}break;}}}}catch(Exception e){e.printStackTrace();}}}}/** * 对beans里面的对象进行实例化 * 并将初始化后的bean对象装入Map * @throws Exception */private void instanceBean(){for(Bean bean:beans){if(bean.getClassName()!=null&&!"".equals(bean.getClassName().trim())){try {singleton.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());} catch (Exception e) {e.printStackTrace();}}}}/** * 解析XML * 使用的是dom4j * 将配置文件下的所有的bean节点的信息装入beans * @param fileName */private void readXML(String fileName) {SAXReader saxReader = new SAXReader();Document document = null;try {URL xmlPath = this.getClass().getClassLoader().getResource(fileName);document = saxReader.read(xmlPath);Map<String , String > nsMap = new HashMap<String , String>();nsMap.put("ns", "http://www.springframework.org/schema/beans"); //加入命名空间XPath xsub = document.createXPath("//ns:beans/ns:bean"); //创建beans/bean的查询路径xsub.setNamespaceURIs(nsMap);List<Element> elemBeans = xsub.selectNodes(document); //查询document下的所有beanfor(Element e: elemBeans){String id = e.attributeValue("id"); //获取bean的id和class属性String className = e.attributeValue("class");XPath propertyXpath = document.createXPath("ns:property");propertyXpath.setNamespaceURIs(nsMap);List<Element> elemProp = propertyXpath.selectNodes(e);System.out.println(elemProp.size());if(elemProp.size() > 0 || elemProp != null){propertys = new ArrayList<Property>();for(Element e1:elemProp){String name = e1.attributeValue("name");String ref = e1.attributeValue("ref");String value = e1.attributeValue("value");System.out.println("property="+name +","+ref);propertys.add(new Property(name, ref ,value));}}else{propertys = null;}//这个propertys只有两种情况:里面有内容或者=nullbeans.add(new Bean(id, className,propertys));//System.out.println(id+","+className+","+propertys.size());} } catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }public Object getBean(String beanName){return this.singleton.get(beanName);}}JUnit测试,记得导入junit的jar包!
import org.junit.BeforeClass;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.silence.service.PersonService;import com.silence.util.MyClassPathXmlApplicationContext;public class SpringTestCase {@BeforeClasspublic static void setUpBeforeClass()throws Exception{}@Test public void instanceSpring(){//ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");MyClassPathXmlApplicationContext ctx = new MyClassPathXmlApplicationContext("beans.xml");PersonService ps = (PersonService) ctx.getBean("personService");ps.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="personService" class="com.silence.service.bean.PersonServiceImpl" > <!-- id不能接受特殊字符 ,name可以接受特殊字符 --> <property name="personDao" ref="personDao"></property> <property name="name" value="silence"></property> </bean> <bean id="personDao" class = "com.silence.service.bean.PersonServiceDaoImpl"></bean> </beans>
结果在我这里是正确通过的!
正在学习spring,目前还没发现有什么比较有意思的地方,功力还有得提高!欢迎探讨!
- Spring笔记——模拟spring的bean管理原理以及依赖注入原理
- spring的管理bean和依赖注入的原理剖析
- 模拟spring的依赖注入原理
- spring依赖注入原理的简单模拟
- Spring学习笔记——Spring依赖注入原理分析
- Spring学习笔记——Sprin管理Bean的原理
- 简单模拟spring装载注入bean原理
- Spring依赖注入的原理
- spring依赖注入原理
- 依赖注入原理 Spring
- spring依赖注入原理
- Spring依赖注入原理
- Spring(二)——Spring管理Bean的原理
- Spring管理Bean的原理
- spring管理bean的原理
- spring管理bean的原理
- spring管理bean的原理
- spring管理bean的原理
- 用代码写相对布局
- Android控件之SlidingDrawer(滑动式抽屉)
- Ubuntu SVN安装配置十分简单
- android animation动画
- 双M结构中,从库提供read服务,单独创建用户的时候建议不写入binlog日志
- Spring笔记——模拟spring的bean管理原理以及依赖注入原理
- windows系统上安装与使用Android NDK
- ubuntu eclipse 加 GBK
- Eclipse 安装C++ 插件
- (必看)C结构体与C结构体之位域(位段)的sizeof问题.
- 展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告
- 对Java中Native关键字的认识
- 不管你学的是什么专业,你都应该多少懂些管理学的东西
- 我奋斗十八年,才能和你一起喝咖啡