本文是Magic AOP:面向切面的业务日志框架设计的第二部分,第一部分请见http://lee5593.iteye.com/admin/show/88163
3.1. 业务日志记录组件设计
业务日志记录组件的设计思路是通过事先定义好的业务类型和操作类型对业务方法进行两个维度的分类,利用BusinessLog注解对需要记录业务日志的业务方法进行声明,然后用AOP对声明了BusinessLog注解的业务方法进行拦截,取到注解中的参数组装业务日志消息对象,调用业务日志输出组件进行输出。
<o:p></o:p>
对一个业务方法进行业务方法进行声明的代码看起来象这样:
java 代码
- @BusinessLog(info="info message")
- public void anService(){…}
-
- @BusinessLog(success="success message",failture="failture message",state=State.VALID)
- public void anotherService(){…}
对于业务日志信息中的会话信息(如用户标识、客户端机器标识),采用了ThreadLocal通过Filter获取后,直接在业务日志消息对象构造方法中进行赋值,以避免客户端开发人员手动编码。
我们推荐使用上述的方式来记录业务日志,当然你也可以将BnLog对象直接注入到你的业务对象中通过显式方法调用来记录业务日志,甚至可以直接拿到BnLogConfiguration对象来按需生成BnLog对象,一切取决于你的喜好,这里只是演示了一种Best Practice。
<o:p></o:p>
业务日志记录组件中的主要接口和类清单如下:
BnLog<o:p></o:p>
业务日志记录接口,包含了多个log方法
BnLogItem<o:p></o:p>
业务日志对象,使用JPA进行数据库表映射,数据库相应的表名需要与对象类名相同。主要属性有业务类型、事件类型、详细信息、记录时间、用户标识、客户端机器标识、是否成功标识。如果扩展该业务日志对象,用JPA对扩展属性进行配置即可,表名需要与扩展对象类名相同。
BnLogConfiguration<o:p></o:p>
业务日志配置类,主要负责初始化业务类型、事件类型和维护业务日志实例缓存池。初始化业务日志框架时,该类从外部的属性文件bnlog.properties中读取定义好的参数,然后分别对业务类型、事件类型以及业务日志消息对象进行初始化,bnlog.properties的格式定义如下:
java 代码
- #----------------------定制业务类型----------------------------------
- #在这里定制业务类型,每个业务类型标识字符串必须是唯一的,且不区分大小写,不能超过50个字符,多个业务类型之间请用,进行分隔。
- #默认内置general类型
- bnlog.businessTypes=general
-
- #----------------------定制事件类型--------------------------
- #在这里定制事件类型,每个事件类型标识字符串必须是唯一的,且不区分大小写,不能超过50个字符,多个事件类型之间请用,进行分隔。
- #默认内置general类型
- bnlog.eventTypes=general
-
- #-----------------------定制业务日志领域对象----------------------
- #在这里定制自己扩展的业务日志领域对象,扩展的业务日志领域对象必须继承基类BnLogItem,并自行实现扩展属性的annotations。
- #如果自行扩展业务日志领域对象,需要修改关系表结构脚本,使之与扩展的业务日志领域对象一致。
- #默认为基类BnLogItem
- bnlog.entityClass=com.relax.component.bnlog.BnLogItem
主要的方法如下:
void init()<o:p></o:p>
初始化方法<o:p></o:p>
<o:p></o:p>
void destory()<o:p></o:p>
销毁方法<o:p></o:p>
<o:p></o:p>
void setBusinessTypes(String businessTypes)<o:p></o:p>
设置业务类型 <o:p></o:p>
<o:p></o:p>
void setEventTypes(String eventTypes)<o:p></o:p>
设置事件类型<o:p></o:p>
<o:p></o:p>
BnLog getBnLog(String name)<o:p></o:p>
获取BnLog实例,所有的BnLog实例都从这里获取<o:p></o:p>
<o:p></o:p>
static boolean validateBusinessType(String businessType)<o:p></o:p>
验证业务类型<o:p></o:p>
<o:p></o:p>
static boolean validateEventType(String eventType)<o:p></o:p>
验证事件类型<o:p> </o:p>
BusinessLog<o:p></o:p>
业务日志注解,用于提供方法级别的声明,配合AOP进行切面业务日志记录。<o:p></o:p>
<o:p>
java 代码
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.METHOD)
- public @interface BusinessLog {
-
-
-
-
- String businessType() default BusinessType.GENERAL;
-
-
-
-
- String eventType() default EventType.GENERAL;
-
-
-
-
- String info() default "";
-
-
-
-
- String success() default "";
-
-
-
-
- String failture() default "";
-
-
-
-
-
- State state() default State.INVALID;
- }
State<o:p></o:p>
业务操作状态枚举,配合BusinessLog注解协同工作。
java 代码
- public enum State {
-
-
-
- INVALID,
-
-
-
- VALID
- }
BnLogAspect<o:p></o:p>
业务日志通用切面,采用@AspectJ风格,Spring配置文件中需引入下列元素来启用对@AspectJ的支持。<o:p></o:p>
java 代码
3.2. 业务日志输出组件
相对于业务日志记录组件,业务日志输出组件要简单得多,我们采用了ActiveMq来对业务日志消息对象进行异步处理,以便隔离业务日志输出异常给业务操作带来的影响。你也可以不用异步处理机制,只需要实现Appender接口,重新编写一种实现来替换默认的输出机制。Appender接口非常简洁,其中只定义了一个doAppend()方法。
<o:p></o:p>
业务日志记录组件中的主要接口和类清单如下:
Appender<o:p></o:p>
业务日志输出接口,定义了一个doAppend(BnLogItem bnLogItem)方法,实现类需实现该方法对业务日志消息对象进行输出
DefaultAppenderImpl<o:p></o:p>
默认的业务日志输出类,实现了Appender接口,将业务日志持久化到数据库
<o:p></o:p>
BnLogMessageProducer<o:p></o:p>
业务日志JMS消息生产者,实现了Appender接口
<o:p></o:p>
BnLogMessageConverter<o:p></o:p>
业务日志消息转换类
<o:p></o:p>
BnLogMessageConsumer<o:p></o:p>
业务日志消息消费者,接受注入的Appender对象对业务日志消息进行真正地输出
3.3. 业务日志查询组件
业务日志查询组件定义了一个BnLogQuery接口,包含了多个查询方法,接口定义如下:
java 代码
- public interface BnLogQuery {
-
- public List<bnlogitem></bnlogitem> listAll();
-
- public List<bnlogitem></bnlogitem> list(String businessType, String eventType);
-
- public List<bnlogitem></bnlogitem> list(String businessType, String eventType,
- Boolean state);
-
- public List<bnlogitem></bnlogitem> list(String businessType, String eventType,
- Boolean state, Date beginTime, Date endTime);
-
- public List<bnlogitem></bnlogitem> list(String hql, Object... values);
-
- public List<bnlogitem></bnlogitem> pageList(String hql, int pageNo, int pageSize,
- Object... values);
-
- }
该查询组件相对来说没有什么难度,本文不再予以详细描述。
4. 总结
本文通过我们在实际企业级项目中应用AOP的实际经验,总结了通过AOP来进行业务日志框架设计的一些经验供大家参考,并希望借此起到抛砖引玉的效果,寻求更加优秀的AOP设计方案,使面向方面软件设计(AOSD)深入人心,来改善目前面向对象设计在某些特定问题领域的不足之处,让我们试目以待。
</o:p>
分享到:
相关推荐
spring-aop面向切面系统日志案例
aop,面向切面编程
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,...
AOP面向切面架构设计Demo
Spring-aop面向切面编程实例 日志系统,权限控制等.
AOP面向切面编程.ppt
一直对AOP面向切面编程的理解很模糊的同学可以看看。
《揭秘AOP:切面编程的综合指南》文章配套演示项目资源
AOP面向切面编程实例,可当作业提交。.net代码亲测,完全正确运行。
AOP(Aspect Oriented Programming):面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。 AOP是对OOP的补充,是软件开发中的一个热点,也是Spring框架中的一个重要内容。 利用AOP...
spring AOP 切面日志 分层打日志
Spring mvc mybatis plus 实现AOP 切面日志系统,带有数据库。可以自行拓展
aop 面向切面编程 demo,通过一个小案例来讲解,aop在andriod开发中运用
Spring,面向切面编程AOP例子!AOP(Aspect Oriented Programming)!
spect Oriented Programming(AOP),面向切面编程,是一个比较热门...AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。
Aop面向切面
本资源将深入探讨软件开发中两个关键的设计和编程概念:三层架构设计模式(MVC)和面向切面编程(AOP)。这两个概念是现代软件开发中不可或缺的组成部分,它们有助于提高代码的可维护性、可扩展性和可重用性。通过...
AOP(面向切面编程).md
aop面向切面编程教学ppt
AOP面向切面思想.mp4