注:由于本工程包含的内容较多。大部分设计图、代码示例不能提供。
请移步至码云clone查看:https://gitee.com/Coodyer/Coody-Framework
本文仅介绍实现思路。
By:Coody 644556636@qq.com
===========================
通过分析Spring表现层。主要包括IOC、AOP两大核心,常用包括MVC、事物管理等。
IOC:依赖注入。
AOP:基于IOC实现的泛持久化动态代理。
MVC:在IOC基础上,基于Servlet实现的拓展性mapping映射。
事务管理:基于AOP并接管数据源实现的事物控制。
==================================================
IOC大致思路如下:
1、建立自己的创建Bean的注解和输出Bean的注解。分别用于Bean头部初始化Bean、字段标识获取Bean。建立自己的初始化接口。用于实现Bean被加载完后执行init方法。
2、用包扫描器扫描监管范围内所有的class、并通过反射扫描所有类是否包含创建Bean的注解进行初始化操作并存储至Bean容器
3、从Bean容器获得所有Bean、并通过反射扫描所有Bean的所有字段是否包含的输出Bean的注解进行赋值操作
4、从Bean容器获得所有Bean、判断是否实现初始化接口并执行init方法。
AOP大致思路如下:
1、创建自己的Around注解,注解参数为Class。创建Aop方法存储容器。本处仅实现环绕通知。
2、在IOC创建Bean之前,优先扫描包下所有类的所有方法,把包含Around注解方法存储至容器。
3、在IOC扫描Bean的时候,检索Bean内部是否包含注解其类型为Around注明的Class。并选择性进行IOC是否需要代理
4、在需要代理的场景下进行切面的调用整合。执行前后进行控制。
MVC大致实现思路如下:
1、创建MVC地址映射相关注解、创建Json输出注解
2、整改IOC,在进行输出Bean之后进行mvc注解扫描。将映射地址和方法存储至mapping容器
3、创建Listen并实现ServletContextListener
4、覆盖contextInitialized方法。接受参数并投递给如上实现的IOC+AOP入口进行加载
5、新建分发器:DispatServlet,在该servlet通过mapping容器获取到Bean、方法
6、新建参数适配器,通过第5步获取到的方法。基于反射技术装载参数并调用执行。
7、执行完成后得到的结果。通过Json输出或转向到模板地址
如图:
事物管理的实现:
1、新建事物管理注解
2、基于如上功能,新建切面,拦截事物管理注解
3、在切面内部。利用线程容器进行控制,是否需要事物。则写入标识
4、在ORM层,优先从线程容器获得连接,没有则创建,并与数据源绑定存储至线程容器。
5、在切面处调用完实际方法后,则关闭线程容器中的连接。
本处献上整合事物管理全过程的录像:
链接: https://pan.baidu.com/s/1eTgMSUm 密码: jxb7
=====================================================
源码地址:https://gitee.com/Coodyer/Coody-Framework
源代码说明:
=================================
更新记录:
2018-02-24:初步研发,实现IOC+AOP
2018-02-25:拓展MVC,基于MVC结合ICO+AOP实现轻量化无依赖类spring开发模式
2018-02-26:整改为maven模式,并整合自写ORM框架配合aop实现事物管理。
=======================================================
- 项目背景:
由于笔者近期参与的一些项目体系未使用到任何框架,而笔者对spring体系特别向往,故此研发本项目。
- 功能说明:
本项目实现注解形式的bean加载、依赖注入、切面等功能。简单实现mvc。
- 项目特点:
本项目使用cglib。秉承轻量、易用、简单、高效等原则。依赖jar:cglib-nodep-3.1.jar fastjson-1.2.31.jar log4j-1.2.17.jar 依赖jar包其余版本自行测试。
- 环境说明:
JDK1.8+
5.目录结构:
- 程序架构:
由于在撰写本文背景下无作图环境,故此略去架构图。以下提供一些结构说明
(1)、包说明
org.coody.framework.entity常用实体包。
org.coody.framework.util 常用工具包
org.coody.framework.box 核心实现包
org.coody.framework.box.adapt 适配器包
org.coody.framework.box.annotation 注解包
org.coody.framework.box.container 容器包
org.coody.framework.box.constant 常量包
org.coody.framework.box.iface 接口包
org.coody.framework.box.init 初始化入口包
org.coody.framework.box.mvc MVC实现包
org.coody.framework.box.proyx 动态代理包
org.coody.framework.box.wrapper 包装类
(2)、类说明-注解
org.coody.framework.box.annotation.Around环绕通知注解标识,用于切面实现
org.coody.framework.box.annotation.InitBean初始化Bean。类似于spring的Service等注解,标记一个bean类
org.coody.framework.box.annotation.JsonSerialize序列化JSON输出,用于controller方法标识。类似于spring的ResponseBody注解
org.coody.framework.box.annotation.OutBean 输出Bean。类似于Resource/AutoWired注解
org.coody.framework.box.annotation.PathBinding 输出Bean。类似于Resource/AutoWired注
(3)、类说明-适配器
org.coody.framework.box.adapt.ParamsAdapt 参数适配器,用于MVC下参数的装载(目前只实现request、response、session三个参数的自动装载)
(4)、类说明-容器
org.coody.framework.box.container.BeanContainer 容器,用于存储bean,类似于spring的application
org.coody.framework.box.container.MappingContainer Mvc映射地址容器
(5)、类说明-接口
org.coody.framework.box.iface.InitFace 初始化接口,凡是实现该接口的bean需实现init方法。在容器启动完成后执行。
(6)、类说明-启动器
org.coody.framework.box.init.BoxRute 容器入口。通过该类的init(packet)方法指定扫描包路径
org.coody.framework.box.init.BoxServletListen 监听器,配置在webxml用于引导容器初始化
(7)、类说明-mvc分发器
org.coody.framework.box.mvc.DispatServlet 类似于spring的DispatServlet
(8)、类说明-代理工具
org.coody.framework.box.proyx.CglibProxy 基于cglib字节码创建子类的实现
(9)、类说明-包装类
org.coody.framework.box.wrapper.AspectWrapper 本处命名可能不尽规范。本类用于多切面的调度和适配
7.使用说明: (1)、web.xml说明
<!-- 配置扫描的包 --> <context-param> <param-name>scanPacket</param-name> <param-value>org.coody.web</param-value> </context-param> <!-- 配置监听器 --> <listener> <listener-class>org.coody.framework.box.init.BoxServletListen</listener-class> </listener> <!-- 初始化分发器 --> <servlet> <servlet-name>DispatServlet</servlet-name> <servlet-class>org.coody.framework.box.mvc.DispatServlet</servlet-class> </servlet> <!-- MVC配置 --> <servlet-mapping> <servlet-name>DispatServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
(2)、MVC使用说明
no.1、在scanPacket指定的包目录下某个类使用@PathBinding("/test")注解。传入参数即该类映射路径
no.2、在方法上面指定@PathBinding("/index.do")注解,传入参数即方法映射路径
no.3、该方法的访问路径为 /test/index.do
no.4、映射方法拓展注解@JsonSerialize 被该注解标识的方法将输出json
no.5、示例:
(3)、IOC使用说明
no.1、在需要初始化为bean的类上指定@InitBean注解
no.2、在需要IOC赋值的字段上指定@OutBean
no.3、示例
通过以上注解,完成整个IOC依赖注入的全过程。
(4)、切面使用说明
no.1、自定义一个注解
no.2、在需要拦截的方法上面标识该注解
no.3、编写一个类,通过@InitBean修饰以实例化bean。在bean内部编写方法。方法用@Around注解修饰。@Around注解传入值为第一步的自定义注解。方法参数类型为AspectWrapper
no.4、在如上操作完成后,凡是包含该自定义注解的方法均通过环绕通知
no.5、示例:
- 实现效果:
- 版权说明:
在本项目源代码中,已有测试demo,包括mvc、切面等示例
作者:Coody
反馈邮箱:644556636@qq.com