Spring AOP初级入门-代码篇之XML

来源:互联网 发布:淘宝助理怎么导入csv 编辑:程序博客网 时间:2024/05/22 10:42

介绍两种实现Spring AOP的代码。xml和@Aspectj注解

XML篇

此切面类中有一些方法在测试时可以

ApplicationContext.xml文件配置Spring相关信息
注意的就是xmlns:引用AOP的头部

<?xml version="1.0" encoding="UTF-8"?><!-- 查找最新的schemaLocation 访问 http://www.springframework.org/schema/ --><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop"    xmlns:context="http://www.springframework.org/schema/context"    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/aop           http://www.springframework.org/schema/aop/spring-aop-4.0.xsd           http://www.springframework.org/schema/beans           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd           http://www.springframework.org/schema/context           http://www.springframework.org/schema/context/spring-context-4.0.xsd           http://www.springframework.org/schema/mvc           http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd           ">    <!-- 利用Schema-based(xml配置)实现 AOP 用到的配置都放在aop:config标签里  start by lily 2015-12-18 -->    <aop:config>        <!-- 配置Aspect(切面类) -->        <aop:aspect id="myAspect" ref="logAspect">            <!-- 配置Pointcut(切入点),表示此路径下的所有类的方法全部可以切入 -->            <aop:pointcut id="logServer" expression="execution(* com.udbac.controller.*Controller.*(..))" />            <!-- 配置advice(通知) ,此通知中所有的method都需要在切面类(LogAspectN.java)中一一对应   stard -->            <aop:before method="before" pointcut-ref="logServer"/><!-- 前置通知 -->            <aop:after-returning method="afterReturning" pointcut-ref="logServer"/><!-- 后置通知 -->            <!--还可配置异常通知,环绕通知,这里不具体写了-->            <!-- 配置advice end -->        </aop:aspect>    </aop:config>    <!--AOP  使用的切面类 -->    <bean id="logAspect" class="com.udbac.util.aop.LogAspectN"></bean>    <!-- AOP 用到的配置  end --></beans>

LogAspectN.java 切面类
本类中可以将所有执行* com.udbac.controller.Controller.(..)此路径下的类的方法全部切入进来

package com.udbac.util.aop;import java.lang.reflect.Method;import javax.servlet.http.HttpServletRequest;import org.aspectj.lang.JoinPoint;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import com.udbac.service.LogService;/*** * Log切面类 ,使用配置XML方式 *  * @date 2015-12-21 * @author lily * */public class LogAspectN {    /**     * 日志管理 接口,此接口的实现类并没有实现其他业务,如果存在业务写在实现类即可。     */    @Autowired(required = true)    private LogService logService;    /***     * 前置通知     * before对应ApplicationContext.xml中的<aop:before method="before" pointcut-ref="logServer"/><!-- 前置通知 -->     * method名称一定要对应上     */    public void before() {        System.out.println("前置通知!!!");    }    /***     * 后置通知     */    public void afterReturning(JoinPoint joinPoint) {        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder                .getRequestAttributes()).getRequest();        // 请求的IP        String ip = request.getRemoteAddr();        try {            // *========控制台输出=========*//            System.out.println("=====后置通知开始=====");            //方法名称            String methodName=joinPoint.getTarget().getClass().getName() + "."                    + joinPoint.getSignature().getName() + "()";            //方法描述            String s_function=getControllerMethodDescription(joinPoint);            //操作内容            String opContent = adminOptionContent(joinPoint.getArgs(), methodName);            System.out.println("请求方法:"+ methodName);            System.out.println("操作模块(方法描述):"+ s_function);            System.out.println("操作内容:"+ opContent);            //创建日志对象            com.udbac.model.Log log = new com.udbac.model.Log();            log.setUserid(logService.loginUserId());//设置管理员id            log.setParameter(opContent);//参数            log.setIp(ip);//ip            log.setMethod(methodName);//请求方法            log.setModule(s_function);//操作模块            log.setOperation("查询");//操作            //调用log日志接口,向数据库中增加日志数据            logService.inserlog(log);//添加日志        } catch (Exception ex) {        }    }     /**       * 获取注解中对方法的描述信息 用于Controller层注解       *       * @param joinPoint 切点       * @return 方法描述       * @throws Exception       */         public  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {            String targetName = joinPoint.getTarget().getClass().getName();            String methodName = joinPoint.getSignature().getName();            Object[] arguments = joinPoint.getArgs();            Class targetClass = Class.forName(targetName);            Method[] methods = targetClass.getMethods();            String description = "";             for (Method method : methods) {                 if (method.getName().equals(methodName)) {                    Class[] clazzs = method.getParameterTypes();                     if (clazzs.length == arguments.length) {                        //获取controller注解中的 name,Log是我在调用controller方法前注解的Log。此处Log可以替换成其他。                    description = method.getAnnotation(Log. class).name();                         break;                    }                }            }             return description;        }       /**     * 使用Java反射来获取被拦截方法(insert、update)的参数值,     * 将参数值拼接为操作内容     */    public String adminOptionContent(Object[] args, String mName) throws Exception{        if (args == null) {            return null;        }        StringBuffer rs = new StringBuffer();        rs.append(mName);        String className = null;        int index = 1;        // 遍历参数对象        for (Object info : args) {            //获取对象类型            className = info.getClass().getName();            className = className.substring(className.lastIndexOf(".") + 1);            rs.append("[参数" + index + ",类型:" + className + ",值:");            // 获取对象的所有方法            Method[] methods = info.getClass().getDeclaredMethods();            // 遍历方法,判断get方法            for (Method method : methods) {                String methodName = method.getName();                // 判断是不是get方法                if (methodName.indexOf("get") == -1) {// 不是get方法                    continue;// 不处理                }                Object rsValue = null;                try {                    // 调用get方法,获取返回值                    rsValue = method.invoke(info);                    if (rsValue == null) {//没有返回值                        continue;                    }                } catch (Exception e) {                    continue;                }                //将值加入内容中                rs.append("(" + methodName + " : " + rsValue + ")");            }            rs.append("]");            index++;        }        return rs.toString();    }}

LogService.java接口
LogService类就是在LogAspectN 类中 引用的接口
例如,在LogAspectN.java中有如下代码:
@Autowired(required = true)
private LogService logService;

package com.udbac.service;import com.udbac.model.Log;/** * 日志记录业务逻辑接口 */public interface LogService {    /**     * 日志记录     * @param log     */    public void inserlog(Log log);    /**     * 获取登录管理员ID     */    public Long loginUserId();}

LogServiceImpl.java实现类

package com.udbac.service.impl;import org.springframework.beans.factory.annotation.Autowired;import com.udbac.service.LogService;import com.udbac.dao.LogMapper;import com.udbac.model.Log;/** * 日志记录业务逻辑接口实现类 * @date 2015-12-18 * @author lily */public class LogServiceImpl implements LogService{    /***     * 由于使用的是MyBatis + Spring MVC结构,这里需要引用MyBatis使用interface      */    @Autowired    private LogMapper logMapper;    public void inserlog(Log log) {        logMapper.insert(log);//调用SQL,sql使用了MyBatis,所以也给insert方法提供了interface        //在实现类里可以处理其他具体业务,这里只做一个测试输出        System.out.println("增加日志具体业务!!!!+++++++++++++++++++++++");    }    @Override    public Long loginUserId() {        // TODO Auto-generated method stub        return null;    }}

其实,在这里大部分Spring AOP的代码已经写完了,至于入库的部分为了以后自己参考也拿出来方便以后查看

LogMapper.java(处理SQL的接口)
本类中的insert()方法正是LogServiceImpl 类中调用的logMapper.insert(log)

package com.udbac.dao;import com.udbac.model.Log;/** * 日志记录Mapper *  * @date 2015-12-18 * @author lily * */public interface LogMapper {    /****     * 添加系统操作日志     * @author lily     * @date 2015-12-18     * @param log     */    public void insert(Log log);}

LogMapper.xml (Mybatis中的SQL)

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.udbac.dao.LogMapper">    <!-- 添加日志记录 --><!--    <select id="select">    select * from tb_virp_system_log();    </select> -->    <insert id="insert" parameterType="map">        INSERT INTO tb_virp_system_log(user_id,create_date,module,method,actions,ip,parameter)        VALUES(#{userid},to_char(now(),'yyyy-mm-dd hh24:hh:ss')::timestamp,#{module},#{method},#{operation},#{ip},#{parameter});    </insert>  </mapper>

使用XML的方式实现AOP大概就是如此,主要在ApplicationContext.xml文件配置以及对应的切面类(LogAspectN )。只要能切入进来,调用相关的业务方法就简单了

下一篇将介绍使用@Aspectj注解方式实现Spring AOP。

1 0
原创粉丝点击