现有业务需求, 让做一个数据权限, 写了一个小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 extends String, ?>) 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;
}
}



