spring 依赖注入

1. 控制反转

依赖对象的创建和维护由应用本身转移到外部容器,即控制权也转移到外部容器中。

2. 依赖注入

依赖对象有外部容器在运行期间动态注入到组件中。

3.所需要的jar包:

clip_image002

4.核心版的spring

(1)spring配置文件放在类路径src下

模板:

<?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"> </beans> 

只要Spring.jar

Commons-logging.jar

这2个jar包即可

(2)然后配置xml,有spring容器管理bean

文件配置Bean有id和name,id不能有特殊字符,但需要有特殊字符时,用name

<bean id="personService" class="com.persia.PersonServiceBean"> <!-- 由spring容器去创建和维护,我们只要获取就可以了 --> </bean>
之后通过上下文来获取bean:
AbstractApplicationContext ctx=new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); IService s=(IService) ctx.getBean("personService"); s.save();

(3)spring依赖注入原理

 public ItcastClassPathXMLApplicationContext(String filename){ this.readXML(filename); this.instanceBeans(); this.injectObject(); }
 先读取配置文件:
 
 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> beans = xsub.selectNodes(document);//获取文档下所有bean节点  for(Element element: beans){ String id = element.attributue("id");//获取id属性值 String clazz = element.attributue("class"); //获取class属性值 BeanDefinition beanDefine = new BeanDefinition(id, clazz); XPath propertysub = element.createXPath("ns:property"); propertysub.setNamespaceURIs(nsMap);//设置命名空间 List<Element> propertys = propertysub.selectNodes(element); for(Element property : propertys){ String propertyName = property.attributue("name"); String propertyref = property.attributue("ref"); PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref); beanDefine.getPropertys().add(propertyDefinition); } beanDefines.add(beanDefine); } }catch(Exception e){ e.printStackTrace(); } }
用一个bean集合来记录xml定义的bean,用一个属性类来代表定义的属性,然后加入bean类里面的属性集合。
第二步是利用反射技术实例化bean
 private void instanceBeans() { for(BeanDefinition beanDefinition : beanDefines){ try { if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim())) sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance()); } catch (Exception e) { e.printStackTrace(); } } }
实例化后的bean保存在一个哈希表中,key为xml定义的id,value为实例。
第三步是为创建的bean注入定义的属性:
 private void injectObject() { for(BeanDefinition beanDefinition : beanDefines){ Object bean = sigletons.get(beanDefinition.getId()); if(bean!=null){ try { PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()){ for(PropertyDescriptor properdesc : ps){ if(propertyDefinition.getName().equals(properdesc.getName())){ Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private if(setter!=null){ Object value = sigletons.get(propertyDefinition.getRef()); setter.setAccessible(true); setter.invoke(bean, value);//把引用对象注入到属性 } break; } } } } catch (Exception e) { } } } }
最后有提供一个getBean的方法供应用程序来获取容器产生的bean:
 public Object getBean(String beanName){ return this.sigletons.get(beanName); }

猜你喜欢

转载自open023.iteye.com/blog/1119527