Spring IOC

spring ioc是spring的核心之一,也是spring体系的基础,那么spring ioc所依赖的底层技术是什么的?反射,以前我们开发程序的时候对象之间的相互调用需要用new来实现,现在所有的bean都是通过spring容器来管理。这样做有什么好处呢?解耦!以前程序直接的调用用new直接给写死了,现在我们可以通过注入不同的接口实现类来完成对象直接的调用。

首先来聊聊Java的反射机制

1、反射机制的作用:

反编译:.class-->.java

通过反射机制访问java对象的属性,方法,构造方法等;

2、Java反射机制用途:

在运行时判断任意一个对象所属的类

在运行时构造任意一个类的对象

在运行时判断任意一个类所具有的成员变量和方法

在运行时调用任意一个对象的方法

3、sun为我们提供了那些反射机制中的类:

1 java.lang.Class; 2 java.lang.reflect.Constructor; 3 java.lang.reflect.Field; 4 java.lang.reflect.Method; 5 java.lang.reflect.Modifier;

4、反射实现的方式

1Class c=Class.forName("className"); 2注明:className必须为全名,也就是得包含包名,比如,cn.xx.UserInfo; 3 4Object obj=c.newInstance(); 5//创建对象的实例 6 7Constructor getConstructor(Class[] params) 8//根据指定参数获得public构造器 9 10Constructor[] getConstructors() 11//获得public的所有构造器 12 13Constructor getDeclaredConstructor(Class[] params) 14//根据指定参数获得public和非public的构造器 15 16Constructor[] getDeclaredConstructors() 17//获得public的所有构造器 18 19ewInstance(); 20//创建对象的实例 21 22获得类方法的方法 23Method getMethod(String name, Class[] params), 24根据方法名,参数类型获得方法 25 26Method[] getMethods() 27//获得所有的public方法 28 29Method getDeclaredMethod(String name, Class[] params) 30//根据方法名和参数类型,获得public和非public的方法 31 32Method[] getDeclaredMethods() 33//获得所以的public和非public方法 34 35获得类中属性的方法 36Field getField(String name) 37//根据变量名得到相应的public变量 38 39Field[] getFields() 40//获得类中所以public的方法 41 42Field getDeclaredField(String name) 43//根据方法名获得public和非public变量 44 45Field[] getDeclaredFields() 46//获得类中所有的public和非public方法

总结一句,以前写的代码,类的熟悉、方法什么东西的都固定了,如果使用反射我们就可以在运行的时候动态的去修改、增删对象的熟悉、方法等等。

spring IOC是如果使用反射来完成对象的注入呢?

1、读取配置文件,或者扫描注解属性

2、根据配置文件,通过反射实例化对象

3、给对象注入依赖的属性

4、放到类似hashMap结构中,供系统调用

1/** 2* 学习版容器 3* 4*/ 5 6public class LeamClassPathXMLApplicationContext { 7 private List<Definition> beanDefines = new ArrayList<Definition>(); 8 private Map<String, Object> sigletons = new HashMap<String, Object>(); 9 10 11 12 public LeamClassPathXMLApplicationContext(String filename){ 13 this.readXML(filename); 14 this.instanceBeans(); 15 this.injectObject(); 16 } 17 18 /** 19 * 为bean对象的属性注入值 20 */ 21 private void injectObject() { 22 for(Definition beanDefinition : beanDefines){ 23 Object bean = sigletons.get(beanDefinition.getId()); 24 if(bean!=null){ 25 try { 26 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); 27 for(ProsDefinition propertyDefinition : beanDefinition.getPropertys()){ 28 for(PropertyDescriptor properdesc : ps){ 29 if(propertyDefinition.getName().equals(properdesc.getName())){ 30 Method setter = properdesc.getWriteMethod();//获取属性的setter方法 31 if(setter!=null){ 32 Object value = sigletons.get(propertyDefinition.getRef()); 33 setter.setAccessible(true); 34 setter.invoke(bean, value);//把引用对象注入到属性 } 35 break; 36 } 37 } 38 } 39 } catch (Exception e) { 40 } 41 } 42 } 43 } 44 45 /** 46 * 完成bean的实例化 47 */ 48 private void instanceBeans() { 49 for(Definition beanDefinition : beanDefines){ 50 try { 51 if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim())) 52 sigletons.put(beanDefinition.getId(), 53 Class.forName(beanDefinition.getClassName()).newInstance()); 54 } catch (Exception e) { 55 e.printStackTrace(); 56 } 57 } 58 } 59 60 /** 61 * 读取xml配置文件 62 * @param filename 63 */ 64 private void readXML(String filename) { 65 SAXReader saxReader = new SAXReader(); 66 Document document=null; 67 try{ 68 URL xmlpath = this.getClass().getClassLoader().getResource(filename); 69 document = saxReader.read(xmlpath); 70 Map<String,String> nsMap = new HashMap<String,String>(); 71 nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间 72 XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径 73 xsub.setNamespaceURIs(nsMap);//设置命名空间 74 List<Element> beans = xsub.selectNodes(document);//获取文档下所有bean节点 75 for(Element element: beans){ 76 String id = element.attributeValue("id");//获取id属性值 77 String clazz = element.attributeValue("class"); //获取class属性值 78 Definition beanDefine = new Definition(id, clazz); 79 XPath propertysub = element.createXPath("ns:property"); 80 propertysub.setNamespaceURIs(nsMap);//设置命名空间 81 List<Element> propertys = propertysub.selectNodes(element); 82 for(Element property : propertys){ 83 String propertyName = property.attributeValue("name");//元素内部引用的属性也获取 84 String propertyref = property.attributeValue("ref"); 85 ProsDefinition propertyDefinition = new ProsDefinition(propertyName, propertyref); 86 beanDefine.getPropertys().add(propertyDefinition); 87 } 88 beanDefines.add(beanDefine); 89 } 90 }catch(Exception e){ 91 e.printStackTrace(); 92 } 93 94 } 95 96 /** 97 98 * 获取bean实例 99 * @param beanName 100 * @return 101 */ 102 public Object getBean(String beanName){ 103 return this.sigletons.get(beanName); 104 } 105 106}

spring ioc核心思想

ioc的思想最核心的地方在于,资源不由使用资源的双方管理,而由不使用资源的第三方管理,这可以带来很多好处。第一,资源集中管理,实现资源的可配置和易管理。第二,降低了使用资源双方的依赖程度,也就是我们说的耦合度。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

一篇文章带你了解JavaScript日期

日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用