SSH(struts+spring+hibernate)迅速开发--第十章 记录日志(2)

来源:互联网 发布:粗集料筛分实验数据 编辑:程序博客网 时间:2024/05/16 05:57

AOP实现登陆的时候,自动记录日志

前面我们有单独实现了用户服务和日志服务,现在我们需要在用户登陆的时候,记录用户登陆信息。按传统的实行方式,需要修改以前实现的登陆逻辑,在登陆代码里面,添加一个语句,调用日志服务里面的方法。这样,就需要实现用户服务的人员专门的去理解日志服务的相关实现,别的服务如果需要日志,也是同样的需要。而且当日志服务发生改变的时候,同时要修改所有调用日志服务的其它服务,这样存在严重的逻辑耦合。

AOP编程思想就根本的解决这样的问题。它能在不修改已经实现了的服务的基础上,实现在执行某个功能方法的时候,自动调用另外一个功能的方法。Spring中有基于AOP编程思想的支持,如下讲解怎么样在Spring中,用AOP编程实现登陆的时候,调用日志服务记录日志。

Spring中实现AOP编程,大体步骤如下:

1.    编写一个通知

2.    注册通知代理

3.    用通知代理代替旧的服务调用

 

接下来详细介绍每一步

1.    编写通知

Spring中的代理有三类:前置通知,后置通知和环绕通知。

前置通知,是在执行目标逻辑前,先执行通知的逻辑

后置通知,是在执行目标逻辑后,再执行通知的逻辑

环绕通知,是通知逻辑完全的包装了目标逻辑的执行,通知可以完全的控制什么时候,是否执行目标逻辑。

我们这里用前置通知,实现登陆的时候,调用日志服务记录日志

编写前置通知,代码清单如下,注意要实现MethodBeforeAdvice接口:

LogAdvice.java

/**

 * 日志类的前置通知

 */

package cn.com.book.demo.advice;

 

import java.lang.reflect.Method;

import java.util.Date;

 

import org.springframework.aop.MethodBeforeAdvice;

 

import cn.com.book.demo.hibernate.dao.Log;

import cn.com.book.demo.services.Logging;

import cn.com.book.demo.services.UserServices;

import cn.com.book.demo.services.impl.LoggingImpl;

 

/**

 * @author Noble.Yang

 *

 */

public class LogAdvice implements MethodBeforeAdvice {

       private Logging log = null;

 

       public void setLog(Logging log) {

              this.log = log;

       }

 

       /*

        * (non-Javadoc)

        *

        * @see org.springframework.aop.MethodBeforeAdvice#before(java.lang.reflect.Method,

        *      java.lang.Object[], java.lang.Object) @param method 正在被调用的目标逻辑的方法

        *      @param params 被调用目标方法的参数 @param target 目标实例

        */

       public void before(Method method, Object[] params, Object target)

                     throws Throwable {

              this.initLog();

              // 当前的目标是不是用户服务实例

              if (target instanceof UserServices) {

                     // 判断当前的方法是否是verifyUser,如果是,就记录日志

                     if (method != null && "verifyUser".equals(method.getName())) {

                            this.log.logging(params[0].toString());

                     }

              }

       }

 

       private void initLog() {

              if (this.log == null) {

                     this.log = new LoggingImpl();

              }

       }

}

 

applicationContext-proxy.xml中,添加如下配置,将刚刚写好的前置通知,注册入Spring

       <!-- 配置日志的前置通知 -->

       <bean id="logAdvice"

             class="cn.com.book.demo.advice.LogAdvice">

         <property name="log">

           <!-- 注册属性实例 -->

           <ref bean="loggingService"/>

         </property>

       </bean>

2.    注册通知代理

通知的代码已经写好,而且注册到Spring了,接下来就是配置通知代理。在applicationContext-proxy.xml中,添加如下配置,完成用户服务的日志通知代理的配置

       <!-- 通知代理 -->

       <bean id=" userserviceLogAdviceProxy"

             class="org.springframework.aop.framework.ProxyFactoryBean">

         <!-- 配置目标接口 -->

         <property name="proxyInterfaces">

           <value>cn.com.book.demo.services.UserServices</value>

         </property>

         <!-- 配置目标实例引用 -->

         <property name="target">

           <ref bean="userService"/>

         </property>

         <!-- 配置通知 -->

         <property name="interceptorNames">

           <list>

             <value>logAdvice</value>

             <!-- 如果有多个通知的话,可以在这里添加 -->

           </list>

         </property>

       </bean>

3.    用通知代理代替旧的服务调用

通知和通知代理都注册好了,接下来就是用配置好得通知代理,代替以前的配置。

在实现通知前,我们对用户服务的调用,是在strutsUserAction里面进行的,现在我们要把以前对userServcie的引用,替换成现在代理通知的引用,具体做法如下:

1)      applicationContext-action.xml中,找到下面的配置

     <bean name="/login" class="cn.com.book.demo.struts.action.UserAction">

           <property name="userService">

              <ref bean="userService"/>

           </property>

       </bean>

2)      把里面的<ref bean=”userService”/>替换成
<ref bean="userserviceLogAdviceProxy"/>,
最后配置如下:

     <bean name="/login" class="cn.com.book.demo.struts.action.UserAction">

           <property name="userService">

              <!-- <ref bean="userService"/> -->

              <ref bean="userserviceLogAdviceProxy"/>

           </property>

       </bean>

3)      到这一步,我们就完成通知,通知代理的开发和配置,运行登陆的时候,系统就会自动通过日志服务,在数据库中添加一个登陆记录。