栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Mvc AOP拦截修改Sql并执行

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Mvc AOP拦截修改Sql并执行

现有业务需求, 让做一个数据权限, 写了一个小Demo, 如果有什么我写的不对的地方, 还请各位大神指教

首先是pom文件, pom.xml

            
            
                4.3.9.RELEASE
                1.9.5
                1.0
                1.6.8_2
                1.0
                3.3.0
            
            
                
                    
                        org.springframework
                        spring-aspects
                        ${spring.version}
                    

                    
                        org.aspectj
                        aspectjtools
                        ${aspectjtools.version}
                    

                    
                        aopalliance
                        aopalliance
                        ${aopalliance.version}
                    

                    
                        cglib
                        cglib
                        ${cglib.version}
                    
                
            

然后是XML, 具体是哪个XML, 看项目具体配置, 我的是自己配的applicationContext-bp-service.xml

applicationContext-bp-service.xml


    
        
        
            
            
            
            
            
        
    

然后就是xml中配置的aop类MySqlIntercept

MySqlIntercept类

package com.test.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.builder.StaticSqlSource;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.text.DateFormat;
import java.util.*;

public class MySqlIntercept {

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    public void before (JoinPoint joinPoint) throws Throwable{
        System.out.println("sql前.....");
    }

    public void afterReturning(){
        System.out.println("sql后");
    }

    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("sql通知");
        Map map = new HashMap<>();
        //获取当前方法
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        String namespace = method.getDeclaringClass().getName();
        String methodName = method.getName();
        //根据namespace+methdoName获取相对应的MappedStatement
        Configuration configuration = sqlSessionFactory.getConfiguration();
        MappedStatement mappedStatement = configuration.getMappedStatement(namespace + "." + methodName);
        //3.获取方法参数列表名
        Parameter[] parameters = method.getParameters();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        for (int i = 0; i < parameterAnnotations.length; i++) {
            Object object = objects[i];
            //说明该参数没有注解,此时该参数可能是实体类,也可能是Map,也可能只是单参数
            if (parameterAnnotations[i].length == 0) {
                if (object.getClass().getClassLoader() == null && object instanceof Map) {
                    map.putAll((Map) object);
                    System.out.println("该对象为Map");
                } else {//形参为自定义实体类
                    map.putAll(objectToMap(object));
                    System.out.println("该对象为用户自定义的对象");
                }
            } else {//说明该参数有注解,且必须为@Param
                for (Annotation annotation : parameterAnnotations[i]) {
                    if (annotation instanceof Param) {
                        map.put(((Param) annotation).value(), object);
                    }
                }
            }
        }
        BoundSql boundSql = mappedStatement.getBoundSql(map);
        List parameterMappings = boundSql.getParameterMappings();
        //这里是新sql, 可以写自己的逻辑        
        String sql = "新sql";
        //下面的就是将修改后的sql放入sqlSessionFactory中
        Field field = boundSql.getClass().getDeclaredField("sql");
        field.setAccessible(true);
        field.set(boundSql, sql);
                                        sqlSessionFactory.getConfiguration().getMappedStatementNames().remove(mappedStatement.getId());
        sqlSessionFactory.getConfiguration().getMappedStatements().remove(mappedStatement);

        SqlSource sqlSource = new StaticSqlSource(configuration, sql, parameterMappings);
        Field mappedStatementField = mappedStatement.getClass().getDeclaredField("sqlSource");
        mappedStatementField.setAccessible(true);
        mappedStatementField.set(mappedStatement, sqlSource);
        sqlSessionFactory.getConfiguration().addMappedStatement(mappedStatement);

        return pjp.proceed();
    }

    
    private static Map objectToMap(Object obj) throws IllegalAccessException {
        Map map = new HashMap<>(16);
        Class clazz = obj.getClass();
        System.out.println(clazz);
        // 获取本类及其父类的属性,↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
        List fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        // 获取本类及其父类的属性,↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
        for (Field field : fieldList) {
            field.setAccessible(true);
            String fieldName = field.getName();
            Object value = field.get(obj);
            map.put(fieldName, value);
        }
        return map;
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1006643.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号