1,开发一个类加载器ClassUtil
加载基础包名下的所有类,比如使用了某注解的类,或者实现了某接口的类,再或者继承了某父类的所有子类;
该类的相关方法:获取类加载器,加载类,获取指定包名下的所有类;
2,定义4个注解类
Action,controller,service,inject
3,助手类ClassHelper
获取应用包名下的所有类,应用包名下所有service类,应用包名下所有controller类。我们将带有controller注解与service注解的类产生的对象,理解为框架所管理的bean,所以有必要在助手类中增加一个获取应用包名下的所有bean类方法(包括service,controller);
用助手类封装了类加载器ClassUtil
4,实现bean容器
1)使用ClassHelper类可以获取所加载的类,但无法同过类来实例化对象,因此需要提供一个反射工具类,封装Java反射相关的API,对外提供更好用的工具方法。即reflerctionUtil实例化对象。
2)存放bean类和bean实例的映射关系:BeanHelper
我们需要获取所有被矿建管理的bean类,此时需要调用classhelper类的getBeanClassSet方法,随后需要循环调用reflectionUtil类的newInstance方法,根据类实例化对象,最后将每次创建的对象存放在静态的Map<Class<?>,Object>中,我们需要随时获取该Map,还需要通过该Map的key类名去获取多对应的value(bean)对象,即Beanhelper类。
5,实现依赖注入功能IOCHelper
即不是开发者通过new的方式来实例化,而是通过框架自身来实例化-》控制反转。
实现依赖注入:先通过beanHelper获取所有BeanMap(记录了类与对象的映射关系)。然后遍历这个映射关系,分别取出bean类和bean实例,进而通过反射获取类中的所有的成员变量。继续遍历这些成员变量,在循环中判断当前成员是否有注解,若带有注解,则从BeanMap 中根据BEan类取出bean实例,最后通过ReflectionUtil#setField方法来修改当前成员变量的值。即IOCHelper类(实现依赖注入)IOC框架中所管理的对象都是单列的,由于IOC框架底层还是从beanhelper中获取bean map的,而beanmap中的对象都是事先创建好并放入这个bean容器中的,所有的对象都是单列的。
6,加载controller
通过classhelper,我们可以获取所有定义了controller注解的类,可以通过反射获取该类中所有带有action注解的方法,获取action注解中的请求表达式,进入获取请求方法与请求路劲,封装一个请求对象(Request)和处理对象(Handler),最后将request与Handler建立一个映射关系,放入一个ActionMap中,并提供一个根据请求方法与请求路劲获取处理对象的方法。
ControllerHelper:变量:Action map:用于存放请求与处理器的映射关系
我们通过ControllerHelper中封装了一个actionmap,通过他来存放request与handler之间的映射关系,然后通过classhelper来获取所有带有controller注解的类,接着遍历这些controller类,从action注解中提取URL,最后初始化request与handler之间的映射关系。
7,初始化框架
我们创建了classhelper,beanhelper, iochelper,controllerHelper,这4个helper类需要通过一个入口程序来加载他们,实际上就是加载他们的静态模块。加载程序:HelperLoader。
8,请求转发器dispatcherservlet
现在我们需要编写一个servlet,让他来处理所有的请求,从httpservletquest对象中获取请求方法与请求路劲,通过controllerHelper#getHandler方法来获取handler对象,当拿到handler对象后,我们可以方便的获取controller类,进而通过beanhelper。getbean方法获取controller的实例对象,对吼可以从httpservletrequest对象中获取所有的请求参数,并将其初始化到一个名为param的对象中。
在param类中,会有一系列的get方法,可通过参数名获取指定类型的参数值,也可以获取所有参数的map结构。
还可从handler对象中获取action的方法的返回值,返回值有两种情况:
1)若返回值是view类型的师徒对象,则返回一个jsp页面‘;
2)若返回值是data类型的数据对象,则返回一个json数据。
通过dispatcherservlet来处理所有的请求,根据请求信息从controllerhelper中获取对应的action方法,然后使用反射技术调用action方法,同时需要具体的传入方法参数,最后拿到返回值并判断返回值的类型,进行相应的处理。
具体代码详见架构探险1.