AspectJ 实现 AOP

175 阅读1分钟
/**
 * @author xyf
 * @date 2021/7/7 13:47
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,})
public @interface aopTest {

}

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("spring_test_aop")
public class ApplicationConfigure {
}

@Aspect
@Component
public class config {

/**
 * Around 表示 before+after  还有其他的方式   这里没有试过、
 * annotation里面写上标志这个切面的注解 @aopTest 这个注解  是设置标注在 Method上的
 * ProceedingJoinPoint 连接点  标识的是 被加注解的方法    现在这个连接点 代表的 就是 testController 的 test【加了@aopTest】方法
 */
@Around("@annotation(spring_test_aop.aopTest)")
public Object testAop(ProceedingJoinPoint joinPoint) throws Throwable {
	Rsp rsp = new Rsp();

	//获取连接点的参数
	Object[] objects = joinPoint.getArgs();
	// 这边可以制作成 log 收集
	System.out.println("连接点的参数:");
	Stream.of(objects).collect(Collectors.toList()).forEach(System.out::println);
	// 获取第一个输入参数 也就是 Req
	Object reqObject = objects[0];
	Req req = (Req) reqObject;

	ArrayList<String> signFlagList = new ArrayList<>();
	ArrayList<String> signValueList = new ArrayList<>();

	Field[] fields = Req.class.getDeclaredFields();
	//这里面可以做参数的校验和参数的加密解密
	for (int i = 0; i < fields.length; i++) {
		fields[i].setAccessible(true);
		String fname = fields[i].getName();
		// 这里需要用已经实例化的 ,有数据的 reqObject 或者是 req
		Object fValue = fields[i].get(reqObject);
		/**
		 * 用注解来表示字段的类型 ,可以将字段分类 ,再做加签解签的时候很方便
		 */
		// 获取注解为SignFlag 的字段值
		SignFlag signFlag = fields[i].getAnnotation(SignFlag.class);
		if (signFlag != null) {
			signFlagList.add(fname+"--"+(fValue == null ? null : fValue.toString()));
		}
		// 获取注解为SignValue 的字段值
		SignValue signValue = fields[i].getAnnotation(SignValue.class);
		if (signValue != null) {
			signValueList.add(fname+"--"+(fValue == null ? null : fValue.toString()));
		}
	}
	Object result = joinPoint.proceed();
	rsp.setMsg( signFlagList.toString() + signValueList.toString() + ((Rsp) result).getMsg());
	// 这边可以制作成 log 收集
	return rsp;
}
}

@Data
@NoArgsConstructor
@Accessors(chain = true)
public class Req {
@SignFlag
private  String name;
@SignValue
private  String password;

}


@Data
@NoArgsConstructor
@Accessors(chain = true)
public class Rsp {
private String msg;
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SignFlag {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SignValue {
}

public class test {


public static void main(String[] args) {
	ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfigure.class);
	System.out.println("test返回:"+applicationContext.getBean(testController.class).test(new Req().setName("张三").setPassword("123")));
}
}

@Component
public class testController {

@aopTest()
public Rsp test(Req req) {
	System.out.println("controller 实现!");
	return  new Rsp().setMsg("controller返回了");
}
}