在以往的项目中,我们要获取一个类的对象,可以通过new或者反射方式的。常规情况下都是用的new的方式。
对象的常见工作是由程序员通过手动new的方式来完成的,Spring框架中有一个IOC的概念,IOC(Inverse Of Control)控制反转。控制反转的含义是将对象的创建工作以及对对象管理工作委托给应用程序来负责。委托给应用程序来处理的好处是:
1.可以调整对象在项目中的个数(单例或者非单例)
2.应用程序可以在创建完对象以后自动给对象中的某些必要属性赋值。例如:在Service对象给SqlSessionFactory赋值。
自定IOC的过程:
分析:
1.需要有一种机制可以将我们需要的对象创建出来(反射机制)
2.如何和应用程序进行沟通,告知它哪些类需要被他创建和管理呢?注解的方式或者xml的方式
3.对象存储在何处?存到集合中使用FactoryBean来进行封装
案例:
1.(框架开发者)先定义一个Component注解,该注解只能添加到类上,有效范围为Runtime。并提供value属性,value用于存储是要创建的这个对象的唯一ID值。
2.(框架使用者)在自己的项目中哪个类需要交给框架来进行创建和管理,就在这个类上添加一个Component注解,并在注解中给ID赋值。
\3. (框架开发者)定义了一个FactoryBean的类,该类的目的是封装框架使用者想要创建的对象的各种信息,例如:
对象ID,对象的Class对象,对象本身,对象类名。
\4. (框架开发者)定义一个BeanFactory类,该类的目的有四个:
扫描注解
读取XML
根据扫描注解和读取XML获得的信息创建对象并封装为FactoryBean对象
提供获取对象的两个API
扫描注解、读取XML、创建对象都是在静态代码块中进行的
扫描注解:
获取classpath目录:
String path=BeanFactory.class.getResource(“/“).getPath().substring(1).replace(“/“,File.separator);
创建classpath目录的File对象,递归判断classpath目录下的所有包的所有文件是否是.class文件,如果是class文件,就获取文件的路径,去掉后缀,将路径中的classpath路径去掉,将斜杠替换为.,最终得到该class文件对应的类名。
将d:/ioc/classes/com/woniuxy/entity/Tiger.class路径转换为com.woniuxy.entity.Tiger
得到类名之后通过反射取出该类的Class对象,通过Class对象判断类上是否存在Component注解。如果存在该注解就通过反射创建它的对象,将id、类名、对象、Class全部封装为一个FactoryBean对象,并存储到一个集合中。
重要API:
c.isAnnotationPresent(Component.class);//判断类上是否有Component注解
Component annotation = (Component)c.getAnnotation(Component.class);
String id = annotation.value();//取出Component注解中的value值,即ID
\5. (框架开发者)允许用户通过xml的方式来描述bean信息,在FactoryBean中读取用户编写的xml文件(文件的格式是框架开发者来定义)。xml文件的格式如下
在静态块中解析xml文件读取所有的bean标签,获取id和类名反射创建对象并封装为FactoryBean对象然后存入到集合中。
\6. (框架开发者)提供getBean方法的两个重载,一个是Class作为参数,一个以ID作为参数,其目的是从集合中遍历出用户想要获取的那个对象。
自定义框架中涉及的类:
