一、什么是IoC
IoC控制反转,由spring来创建对象并进行对象装配,解决类与类之间的耦合
二、Demo开始,我们创建一个自动装配的的类模拟IoC的功能
1、spring中包扫描@Service能在spring容器中创建bean,首先我们定义自己的@MyService
2、spring中的@Autowirted能自动装配,我们定义自己的@MyIoc
3、spring中用ClassPathXmlApplicationContext进行加载xml文件,我们定义一个自己的类,构造方法需要一个包名字符串。
4、首先我们看构造方法,会进行创建一个map来充当bean的容器和一个cacheField的map来充当一个装有@MyIoc注解的变量,后面我们会用到,这里不明白也没关系。
我们看newInstance()方法,这里我将放进来的包名进行一个工具类的执行,像spring中的@CompontScan进行包扫描得到包下面所有的类的字节码(该字节码是一个以类名称首字母小写为key的map)并将字节码赋值给成员变量,有兴趣的童鞋可以问我要源码自己看一下。这里我们主要讲IoC。
然后我们可以看到循环走doCreateBean()方法跟spring中的方法尽量保持同名称方便理解,进行一个创建bean的过程,接下来我们看doCreateBean()方法
在该方法中主要三大方法进行,在三大方法之前会对beans(就是成员变量中的map)进行一个获取是否创建过该bean跟spring中一样,toFirstSmll()方法是进行将名称首字母变成小写。然后走三大方法,第一个方法Instance()是创建bean的方法也就是通过反射进行创建对象(注意spring中是无参构造进行的创建对象,我这里为了方便),第二个方法是apply()是进行将该对象中的所有的加了我们定义的@MyIoc注解的变量装入到一个以类名称首字母小写为key的,value为list的map中(该map就是我们成员变量中的cacheField),接下来我们看第三个方法init()方法,该方法就是对创建好的对象进行bean的自动装配。
5、首先我们第一个方法Instance(),toFirstSmll()方法就是对名称进行一个首字母小写的变化,后面就不再解释。可以看到直接创建对象并以类名称首字母小写的方式放入beans中,为了创建对象时先进行判断是否创建过因为我们会递归这个doCreateBean()方法,注意spring中默认是无参构造创建的,再次强调。
6、接着我们第二个方法apply(),该方法是获取类的所有变量并进行循环访问是否有@MyIoc注解,有个话装进list中,最终放入cacheField的map中缓存起来,以类首字母小写的姓氏。
7、最后init()方法,我们看到首先回去cacheField中进行找到该bean的缓存好的所有变量的list,如果该list为null则说明这个类并没有加@MyIoc的注解的变量则什么也不做。有的话则进行查找beans容器中是否有该需要注入的类对象,没有也就会重新走doCreateBean()方法再次对类进行创建对象和初始化,也就是说我们创建一个bean的时候可能会去创建另一个bean,那到创建这个bean的时候怎么办我们对doCreateBean()方法中第一个就去判断是否创建过该bean。走完doCreateBean()方法,beans容器中也就有了该bean并对它进行注入。整个注入完后对该bean的缓存有@MyIoc注解变量list进行移除也就是最后的cacheFidle.remove(name);
这是getBean()方法和toFirstSmll()方法
注意!注意!注意!
@MyIoc的变量名必须必须和类名保持一致并且首字母小写,因为我写死了
二、最后总结
也就是创建实例,缓存其中的注解变量,初始化实例。
在整个的一个bean创建的过程中有可能去创建另一个bean,所有在创建bean之前就判断是否创建过该bean。
想要了解该工具类如何做到spring中的包扫描问我要源码
想要源码参考的关注加留言邮箱!qq1820571641,记得关注(原创很累)。如果有错误及时告知或者欢迎纠错。