1.首先在spring mvc 的配置文件中确定扫描包
<context:component-scan base-package=“com.sun.controller,com.sun.annotation” />
2.其次配置aop aspectj 自动注解识别
<aop:aspectj-autoproxy proxy-target-class=“true”/>
3.自定义注解类
package com.sun.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)//定义了该Annotation被保留的时间长短(1.SOURCE:在源文件中有效(即源文件保留)2.CLASS:在class文件中有效(即class保留)3.RUNTIME:在运行时有效(即运行时保留))
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})//Annotation所修饰的对象范围 属性,方法,类等
//@Documented//描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化
//@Inherited //元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类
public @interface First {
String value() default "";
int num();
}
4.自定义的Aspect切面类
package com.sun.annotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class AspectJ {
public AspectJ(){
System.out.println("AspectJ---加载");
}
// @Pointcut("execution(public * com.sun.controller.*.*(..))")//定义作用的方法范围
// @Pointcut("@annotation(com.sun.annotation.First)")//定义作用的注解
@Pointcut("execution(@com.sun.annotation.First public * com.sun.controller.*.*(..))")//定义作用的注解+方法范围
public void t(){}
@Before("t()")
public void t1(JoinPoint joinPoint){
System.out.println("t1");
Object[] args = joinPoint.getArgs();//获得切面方法当中的参数
MethodSignature signature = (MethodSignature) joinPoint.getSignature();//获得切面当中方法签名
Method method = signature.getMethod();//获得签名方法
First first = signature.getMethod().getAnnotation(First.class);//获得方法上的注解
if(first.num()==1){
System.out.println("允许访问");
}else{
throw new RuntimeException("false");
}
//List<Long> ids = resolveVar(first.value(), args, signature);
}
@After("t()")
public void t2(JoinPoint joinPoint){
System.out.println("t2");
}
@AfterReturning("t()")
public void t3(JoinPoint joinPoint){
System.out.println("t3");
}
@AfterThrowing("t()")
public void t4(JoinPoint joinPoint){
System.out.println("t4");
}
/**
* 解析ids
* @param var
* @param args
* @param signature
* @return
*/
private List<Long> resolveVar(String var, Object[] args, MethodSignature signature) {
if(StringUtils.isEmpty(var)) {
return new ArrayList<>();
}
// 先通过 . 分割
String[] varSplit = StringUtils.split(var, '.');//如注解值为user.id
// 获取方法入参名称列表
String[] parameterNames = signature.getParameterNames();//如入参User user,Role role
// 找到入参对应的index
int index = 0;
for(int i = 0; i < parameterNames.length; i++) {
if(parameterNames[i].equals(varSplit[0])) {//varSplit[0]=user,parameterNames[0]=user
index = i;
break;
}
}
Object arg = args[index];
Class clazz = signature.getParameterTypes()[index];
for(int i = 1; i < varSplit.length; i++) {
// 查找字段
Field field = ReflectionUtils.findField(clazz, varSplit[i]);//从User中找到属性为id的field
if(field == null) {
throw new RuntimeException("id变量不存在, var:" + var);
}
field.setAccessible(true);
try {
arg = field.get(arg);
clazz = field.getType();
} catch (IllegalAccessException e) {
throw new RuntimeException("id变量不存在, var:" + var, e);
}
}
return arg == null ? new ArrayList<>() : getIds(arg);
}
private List<Long> getIds(Object arg) {
if(arg instanceof Long) {
return Collections.singletonList((Long) arg);
} else if(arg instanceof List) {
return (List<Long>) arg;
} else if(arg instanceof Long[]) {
return Arrays.asList((Long[])arg);
} else {
throw new RuntimeException("只支持配置Long或者List<Long>类型团队id, 解析后的类型:" + arg.getClass().toGenericString());
}
}
}
5.调用的方法
@First(value = "s",num = 1)
@RequestMapping("/echarts")
public String echarts(){
System.out.println("****chartsTest***");
return "chartsTest";
}
@First(value = "s",num = 2)
@RequestMapping("/getPeoplelrData")
@ResponseBody
public Object getPeoplelrList(){
System.out.println("*******");
List<Peoplelr> r = peoplelrService.getPeoplelrList();
return r;
}
调用echarts 允许访问,调用getPeoplelrList 抛出异常
版权声明:本文为qq_25210899原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。