JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
目标:通过配置切面,实现在执行特定包下的方法前,对方法参数部分属性进行赋值
场景:参数类型不固定,但是所有参数类型都有同一父类(存放认证信息),这里是给父类里的私有认证信息属性进行赋值
//加入IOC容器中
@Component
//切面
@Aspect
public class XXXHandler {
//读取配置文件的值赋给aaa变量,下同
@Value("${XXX}")
public String aaa;
@Value("${XXX}")
public String bbb;
//切到service包下以及子包下任意方法
@Before("execution(* cn.com.xx.service..*.*(..))")
public void doBefore(JoinPoint joinPoint) {
try {
//获取参数
Object[] o = joinPoint.getArgs();
for (int i = 0; i < o.length; i++) {
System.out.println("类名:"+joinPoint.getTarget().getClass().getName()+
"方法名:"+joinPoint.getSignature().getName());
//1.加载类
String name = o[i].getClass().getName();
Class clz = Class.forName(name);
//2.获取当前类包含其父类的全部属性
//clz.getDeclaredFields()只能获取当前类的属性,无法获取父类的,所以需要通过递
//归的方式遍历
List<Field> fieldList = new ArrayList<>();
while(clz != null){
fieldList.addAll(Arrays.asList(clz.getDeclaredFields()));
clz = clz.getSuperclass();
}
//3.匹配到当前对象的authentication属性,赋值
for(Field field : fieldList){
if(("xxx").equals(field.getName())){
//如果此属性为非public属性的情况时,需要设置属性可达,否则会抛出
//IllegalAccessException异常
field.setAccessible(true);
MyAuthentication authentication = new MyAuthentication(aaa,bbb);
//赋值
field.set(o[i],authentication);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}