参照Spring源代码我写了一个方法调用监视器,和声明式事务一样,这是个声明式监视器。本人只是为了学习之用,分享在这里,也许可以对某些人有些用。
先介绍一个最简单的使用例子:
1.配置。在Spring容器的配置文件中加入如下配置:
2. 确保CallMonitor.jar在你的类目录下。
还依赖这些类库:commons-logging.jar, spring.jar(2.5). cglib-nodep-2.1_3.jar。
3. 在你的方法头上加入注解,例如:
注意这里以Spring自己的Petclinic为例。
这就完事。当运行完这个方法时,系统会打印出日志:
[Call Monitor] - <org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic.findOwners(java.lang.String)[Run Time: 134][Parameter Data: frank]>
[b]功能说明:[/b]
1.注解定义。
2.配置定义。
<monitor:annotation-driven proxy-target-class="false" order="0"/>
proxy-target-class, 值为true即启用cgLib代理,值为false则是缺省的JDK代理。用cgLib时你只能把注解定义在目标类,不能在接口上。
order,类似优先级的概念,值越小则越优先。比如当目标方法还有一个事务的注解,你可以用这个值来控制两个拦截器的执行顺序。
[b]实现思路[/b]
1.MonitorNamespaceHandler,来处理配置文件的命名空间。
CallMonitor.jar里面的META-INF里有两个文件:
spring.handlers, Spring读取此文件来找到配置文件里monitor命名空间的解析器,即MonitorNamespaceHandler。
spring.schemas,Spring读取此文件来找到相应的xsd文件。
2.MonitorAnnotationDrivenBeanDefinitionParser,来解析monitor:annotation-driven配置项,产生相关的类的定义。
3.MonitorAnnotationParser,来解析注解实例。
4.BeanFactoryMonitorAttributeSourceAdvisor,Spring用这个advisor来检查每一个生成的类是否包含@CallMonitoring,有的话则产生相应的代理。
5.MonitorInterceptor,拦截器,业务逻辑全在这里。
源代码请参见附件,欢迎下载和评论。
先介绍一个最简单的使用例子:
1.配置。在Spring容器的配置文件中加入如下配置:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:monitor="http://www.mycompany.org/schema/monitor"
xsi:schemaLocation="
http://www.mycompany.org/schema/monitor http://www.mycompany.org/schema/monitor/monitor-1.0.xsd">
...
<monitor:annotation-driven/>
...
</beans>
2. 确保CallMonitor.jar在你的类目录下。
还依赖这些类库:commons-logging.jar, spring.jar(2.5). cglib-nodep-2.1_3.jar。
3. 在你的方法头上加入注解,例如:
@CallMonitoring(logData = true)
public Collection<Owner> findOwners(String lastName)
...
注意这里以Spring自己的Petclinic为例。
这就完事。当运行完这个方法时,系统会打印出日志:
[Call Monitor] - <org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic.findOwners(java.lang.String)[Run Time: 134][Parameter Data: frank]>
[b]功能说明:[/b]
1.注解定义。
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CallMonitoring {
/**
* 累计调用次数和时间,以方法为单位。
* @return
*/
boolean accumulate() default false;
/**
* 记录方法传入的参数值,实际取toString值。
* @return
*/
boolean logData() default false;
/**
* 方法运行时间。
* @return
*/
boolean logTime() default true;
}
2.配置定义。
<monitor:annotation-driven proxy-target-class="false" order="0"/>
proxy-target-class, 值为true即启用cgLib代理,值为false则是缺省的JDK代理。用cgLib时你只能把注解定义在目标类,不能在接口上。
order,类似优先级的概念,值越小则越优先。比如当目标方法还有一个事务的注解,你可以用这个值来控制两个拦截器的执行顺序。
[b]实现思路[/b]
1.MonitorNamespaceHandler,来处理配置文件的命名空间。
CallMonitor.jar里面的META-INF里有两个文件:
spring.handlers, Spring读取此文件来找到配置文件里monitor命名空间的解析器,即MonitorNamespaceHandler。
spring.schemas,Spring读取此文件来找到相应的xsd文件。
2.MonitorAnnotationDrivenBeanDefinitionParser,来解析monitor:annotation-driven配置项,产生相关的类的定义。
3.MonitorAnnotationParser,来解析注解实例。
4.BeanFactoryMonitorAttributeSourceAdvisor,Spring用这个advisor来检查每一个生成的类是否包含@CallMonitoring,有的话则产生相应的代理。
5.MonitorInterceptor,拦截器,业务逻辑全在这里。
源代码请参见附件,欢迎下载和评论。