当tomcat启动时,由web.xml配置信息中初始化ActionServlet类和CharsetFilter类,启动顺序可由load-on-startup配置。
ActionServlet继承HttpSetvlet类,由init(SetvletConfig)方法启动,执行initEasyJWeb()方法进行初始化:
1.设置资源加载器FrameworkLoader,利用DefaultWebConfig读取配置文件(默认为WEB-INF/easyjf-web.xml,也可在web.xml中更改配置路径如①所示)
获得modules,forms,pages,beans,initApp,interceptors,errorHandler,ajaxConfigManager,全局属性配置等(配置文件格式及全局属性见②)可通过webConfig调用。
其中所有module另以bean形式保存为bean。easyjweb内置了IOC容器,bean类型的自动注入处理见③。
设置DefaultContainer,注册配置的bean并加载及注册defaultActionPackage中的bean(@Bean注解)以及module(以Action结尾),处理module的别名alias(配置文件以及Action包中的module)
2.初始化所有scope为singleton或application且不是lazy的bean(默认scope为singleton),如果配置了factory-method则执行无参方法,或者根据constructor-arg配置构造类实例,并在SingletonBeanContainer中注册。
然后根据bean配置信息进行setter注入:根据bean中需要注入property的value类型处理(用BeanConfigReader读取配置bean时得到)
1、如果是BeanDefinition,则按照getBean(name)获得bean,
2、AutoInject类型(支持toPO自动注入),则按照注解指定的bean名或者属性类型获得获得bean,没有则抛出BeansException,
3、普通类型(如String,Collection等)不更改,
最后用com.easyjf.beans.BeanWrapper实现setter方法注入。
3.将webConfig以及container保存到FrameworkEngine中,便于调用;初始化Ajax服务(保存ajax配置信息),模板(配置velocity),启动initApp
在ServletContext中设置容器属性Globals.CONTAINER_CONTEXT,并把ActionServlet设置到FrameworkEngine,便于调用
4.启动完毕
①
②
property结构:
<frame-setting>的property
TemplateBasePath: 模版根目录路径;
com.easyjweb.debug: 是否调试模式;
com.easyjweb.maxUploadFileSize: 文件最大上传值(*1024);
com.easyjweb.uploadSizeThreshold:上传文件缓存大小;
com.easyjweb.maxDirectJumpToActionTimes:最大直接跳转Action次数;
com.easyjweb.permissionVerify:是否自动检查权限;
com.easyjweb.messageResourceLoader:设置全局变量Globals.LOAD_MESSAGE_RESOURCE_FROM_PATH的值为true,这样即可从类加载器加载消息资源,可以提高性能,适合在产品发布的时使用
com.easyjweb.language:设置全局变量Globals.Language的值为指定的语言,这样就可以使得EasyJWeb后台输出指定语言的日志;
com.easyjweb.propertiesType:设置资源文件的默认格式;
com.easyjweb.defaultActionPackages:系统中配置需要扫描的包,多个包用','隔开
③
处理bean的自动注入BeanConfigReader:handleAutoInject(BeanDefinition bean, String autoInject)
autoInject是文件中配置的inject值,默认为none。
首先,获得该beanDefinition及其父类所有属性,如果已经在文件中配置property,则不作处理(在从配置文件得到的property均已设置好注入类型,见②)
若未配置则依次检查(主要用于前台数据传递时toPO自动注入):1、注解方式:@Inject,默认为AutoJnjectByType,若@Inject(name="service")按照service名注入(在配置文件中必须有bean的name配成service);2、bean配置的inject非none且无InjectDisable注解则按属性类型注入,最后按注入名name或者属性类型type以AutoInject(type|name)类型保存到bean的property中。
所以,如果属性配置了注解@Inject,则一定需要在配置property属性,否则报错"找不到指定的bean",若配置文件中bean的inject配置为非none,则不需要注入的属性必须注解为@InjectDisable
④DefaultContainer中
getBean(String name|Class type)顺序:1、SingletionBean(均已实例化)2、beanDefinitions中,存在则实例化 3、查询所有innerContainer
getBeanDefinition(Class type):查询beanDefinitions,得到第一个是type类型或其父类型的bean
getBeans(Class<T> type):查询SingletionBean、innerContainer中所有满足type的bean,如果type时Order类型,进行排序处理,最终放回List<T>