使用AOP去切入private,导致属性注入失败的问题

1.背景

最近项目中使用了数据字典,在写订单模块时会经常在映射方法中将订单的类型和订单的状态放到request域或model域中。
由于订单模块业务映射很多,一个个添加太麻烦,所以想到AOP来实现。

 

 2.问题描述

自己写了一个AOP,访问时发现,有些映射访问错误,属性注入为空

 

 3.aop代码

package com.chongdong.web.common.aspect;

import com.chongdong.common.dict.ListTypeParameter;
import com.chongdong.common.log.Log;
import com.chongdong.common.log.LogFactory;
import com.chongdong.web.common.annotation.OrderDictData;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.ui.ModelMap;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @Description 加载订单相关字典表数据
 * @Author: yanxh<br>
 * @Date 2019/11/4 9:57<br>
 * @Version 1.0<br>
 */
@Aspect
@Component("orderDictDataAspect")
public class OrderDictDataAspect {
	
	final static Log log = LogFactory.getLogger(OrderDictDataAspect.class);

	public OrderDictDataAspect() {log.info("加载订单字典数据的切面");}

	/**
	 * @Description 配置切入点
	 * @Author: yanxh<br>
	 * @Date 2019/11/4 9:59<br>
	 * @Version 1.0<br>
	 */
	@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
	public void pointCut() {}

	/**
	 * 后置通知
	 * @param joinPoint
	 */
	@AfterReturning(returning="returnValue",value="pointCut()")
	public void afterReturning(JoinPoint joinPoint, Object returnValue) {
		setOrderDictData(joinPoint, null, returnValue);
	}

	/**
	 * 拦截异常操作,有异常时执行
	 * @param joinPoint
	 * @param e
	 */
	@AfterThrowing(value = "pointCut()", throwing = "e")
	public void afterThrowing(JoinPoint joinPoint, Exception e) {
		setOrderDictData(joinPoint, e, null);
	}

	/**
	 * @Description 设置订单数据字典
	 * @Author: yanxh<br>
	 * @Date 2019/11/4 13:54<br>
	 * @Version 1.0<br>
	 */
	private void setOrderDictData(JoinPoint joinPoint, Exception e, Object returnValue) {
		try {
			// 获取切入的类
			Object target = joinPoint.getTarget();

			// 非注解引用类,直接跳过
			if(!target.getClass().isAnnotationPresent(OrderDictData.class)){
				return;
			}

			// 获得注解
			Signature signature = joinPoint.getSignature();
			MethodSignature methodSignature = (MethodSignature) signature;

			// 获取目标类的方法
			Method method = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());

			// 获取拦截的请求参数
			Object[] args = joinPoint.getArgs();

			/**
			 * 加载订单相关字典表数据
			 */
			// 这里获取所有的参数
			Class<?>[] clas = method.getParameterTypes();

			for (int i=0; i<clas.length; i++){
				//根据参数名称,做某些处理
				String requestParam = clas[i].getSimpleName();

				// 获取request请求
				if ("HttpServletRequest".equals(requestParam)){
					HttpServletRequest request = (HttpServletRequest)args[i];
					// 订单类型
					request.setAttribute("orderTypeList", ListTypeParameter.ORDER_TYPE);
					// 订单状态
					request.setAttribute("orderStatusList", ListTypeParameter.ORDER_STATUS);
					break;
				}
				// 获取model请求
				if ("ModelMap".equals(requestParam)){
					ModelMap model = (ModelMap)args[i];
					// 订单类型
					model.addAttribute("orderTypeList", ListTypeParameter.ORDER_TYPE);
					// 订单状态
					model.addAttribute("orderStatusList", ListTypeParameter.ORDER_STATUS);
					break;
				}
			}

		} catch (Exception exp) {
			// 记录本地异常日志
			log.error("设置订单字典数据出错,异常信息:{"+exp.getMessage()+"}");
			exp.printStackTrace();
		}
	}

}

 

 4.原因

对比发现,映射的方法用private进行了访问限制,改为public即可

 

5.总结 

AOP切入的方法,其访问权限为protected/public,如果匹配private时,会导致其方法中所有的属性注入 注入失败。

 

 

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值