SpringAOP笔记

AOP记录, 它可以做很多的事情. 留着查看


1.日志处理

2.权限处理

3.限制,异常控制


package com.pahaoche.portal.qiantai.weizhang.aop;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.pahaoche.portal.base.memcached.MemcachedService;

@Aspect
@Component("systemLogAspect")
public class SystemLogAspect {
	
	private Log logger = LogFactory.getLog(SystemLogAspect.class);
	
	@Autowired
	@Qualifier("memcachedService")
	private MemcachedService memcachedService;
	
	/**
	 * 频繁请求控制
	 */
	@Pointcut("@annotation(com.pahaoche.portal.qiantai.weizhang.aop.FrequentRequestAsp)")  
	public void pointCutFrequentLog(){}
	
	@Pointcut("@annotation(com.pahaoche.portal.qiantai.weizhang.aop.SystemControllerLog)")
    public void pointCutMethod() {}
	/**
	 * controller 执行消耗时间ms
	 */
	@Pointcut("execution(public * com.pahaoche.portal.qiantai.weizhang.controller.*Controller.*(..))")
	public void pointCutUseTime(){}
	/**
	 * service 方法执行消耗时间ms
	 */
	@Pointcut("execution(public * com.pahaoche.portal.base.weizhang.service..*.*(..))")
	public void pointCutServiceUseTime(){}
	
	
	@Before("pointCutMethod()")
	public void doBefore() {
		
	}
	@Around("pointCutUseTime()")
	public Object doAroundUseTime(ProceedingJoinPoint pjp) throws Throwable{
		Long startTime = System.currentTimeMillis();
        String ip = getRemoteAddr();
		String className = pjp.getSignature().getDeclaringType().getName();
		String methodName = pjp.getSignature().getName();
		Object o = pjp.proceed();	
		Long endTime = System.currentTimeMillis();
		logger.info("controller:"+methodName+"(),useTime:"+(endTime-startTime)+"ms."+"path:"+className+"."+methodName+"()"+";IP:"+ip);
		return o;  
	}
	
	
	@Around("pointCutServiceUseTime()")
	public Object doAroundServiceUseTime(ProceedingJoinPoint pjp) throws Throwable{
		Long startTime = System.currentTimeMillis();
		String className = pjp.getSignature().getDeclaringType().getName();
		String methodName = pjp.getSignature().getName();
		Object o = pjp.proceed();	
		Long endTime = System.currentTimeMillis();
        logger.info("service:"+methodName+"(),useTime:"+(endTime-startTime)+"ms."+"path:"+className+"."+methodName+"()");
		return o;  
	}
	
	
	@Around("pointCutFrequentLog()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {  
        String ip = getRemoteAddr();
        String methodName = pjp.getSignature().getName();
        Object o = null;
        //IP不为null时做判断
        if(StringUtils.isNotEmpty(ip) && checkIpMemcached(ip, methodName)){
        	logger.info("频繁请求不处理. IP:"+ip+";methodName:"+methodName);
        }else{
        	o = pjp.proceed();	
        }
        return o;  
    }  
	
	private String getRemoteAddr(){
		String ip = "";
		if(null == RequestContextHolder.getRequestAttributes() 
				|| null == ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()){
			return  ip;
		}
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        ip = request.getHeader("x-forwarded-for"); 
        if(StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { 
            ip = request.getHeader("Proxy-Client-IP"); 
            if(StringUtils.isNotEmpty(ip) && !"unknown".equalsIgnoreCase(ip)){
            	ip +="#Proxy-Client-IP";	
            }
        } 
        if(StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { 
            ip = request.getHeader("WL-Proxy-Client-IP");
            if(StringUtils.isNotEmpty(ip) && !"unknown".equalsIgnoreCase(ip)){
            	ip +="#WL-Proxy-Client-IP";
            }
        } 
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
            if(StringUtils.isNotEmpty(ip) && !"unknown".equalsIgnoreCase(ip)){
            	ip +="#HTTP_CLIENT_IP";
            }
        }
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            if(StringUtils.isNotEmpty(ip) && !"unknown".equalsIgnoreCase(ip)){
            	ip +="#HTTP_X_FORWARDED_FOR";
            }
        }
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if(StringUtils.isNotEmpty(ip) && !"unknown".equalsIgnoreCase(ip)){
            	ip +="#RemoteAddr";
            }
        }
        return ip;
        /*
         * 
         * 	可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?
			答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
			如:
			X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100 
			用户真实IP为: 192.168.1.110
         * 
         */
	}
	
	/**
	 * 如果6秒内同一个IP对同一个方法有请求,则不作处理
	 * @param ip
	 * @param methodName
	 * @return
	 */
	private boolean checkIpMemcached(String ip,String methodName){
		String key =(ip+":"+methodName).replace(",", "%").replace(".", "$");
		//wwwtest.pahaoche.com:202.69.18.197, 172.30.50.250:resultViolation
		if(key.length() > 40){
			logger.warn("Key too long. key="+key);
			return false;
		}
		Long currentTime = System.currentTimeMillis();
		int exp = 20 ; //过期时间, 单位秒
		if(null == memcachedService.get(key)){
			memcachedService.set(key,exp,currentTime);	
		}else{
			Long oldTime = (Long)memcachedService.get(key);
			if(currentTime - oldTime   < (6*1000)){
				return true;
			}else{
				memcachedService.set(key,exp,currentTime);
				logger.info("更新IP:methodName缓存. key="+key);
			}
		}
		return false;
	}

	
	/**
	 * 获取注解中对方法的描述信息 用于Controller层注解
	 * 
	 * @param joinPoint
	 *            切点
	 * @return 方法描述
	 * @throws Exception
	 */
	public static String getControllerMethodDescription(ProceedingJoinPoint joinPoint) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class targetClass = Class.forName(targetName);
		Method[] methods = targetClass.getMethods();
		String description = "";
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				Class[] clazzs = method.getParameterTypes();
				if (clazzs.length == arguments.length) {
					description = method.getAnnotation(SystemControllerLog.class).description();
					break;
				}
			}
		}
		return description;
	}
	
}

applicationContext.xml中加入aop注解扫描,如果controller需要用到aop,将spring-mvc.xml配置即可。

<aop:aspectj-autoproxy proxy-target-class="true"/>  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 智慧社区背景与挑战 随着城市化的快速发展,社区面临健康、安全、邻里关系和服务质量等多方面的挑战。华为技术有限公司提出智慧社区解决方案,旨在通过先进的数字化技术应对这些问题,提升城市社区的生活质量。 2. 技术推动智慧社区发展 技术进步,特别是数字化、无线化、移动化和物联化,为城市社区的智慧化提供了可能。这些技术的应用不仅提高了社区的运行效率,也增强了居民的便利性和安全性。 3. 智慧社区的核心价值 智慧社区承载了智慧城市的核心价值,通过全面信息化处理,实现对城市各个方面的数字网络化管理、服务与决策功能,从而提升社会服务效率,整合社会服务资源。 4. 多层次、全方位的智慧社区服务 智慧社区通过构建和谐、温情、平安和健康四大社区模块,满足社区居民的多层次需求。这些服务模块包括社区医疗、安全监控、情感沟通和健康监测等。 5. 智慧社区技术框架 智慧社区技术框架强调统一平台的建设,设立数据中心,构建基础网络,并通过分层建设,实现平台能力及应用的可持续成长和扩展。 6. 感知统一平台与服务方案 感知统一平台是智慧社区的关键组成部分,通过统一的RFID身份识别和信息管理,实现社区服务的智能化和便捷化。同时,提供社区内外监控、紧急救助服务和便民服务等。 7. 健康社区的构建 健康社区模块专注于为居民提供健康管理服务,通过整合医疗资源和居民接入,实现远程医疗、慢性病管理和紧急救助等功能,推动医疗模式从治疗向预防转变。 8. 平安社区的安全保障 平安社区通过闭路电视监控、防盗报警和紧急求助等技术,保障社区居民的人身和财产安全,实现社区环境的实时监控和智能分析。 9. 温情社区的情感沟通 温情社区着重于建立社区居民间的情感联系,通过组织社区活动、一键呼叫服务和互帮互助平台,增强邻里间的交流和互助。 10. 和谐社区的资源整合 和谐社区作为社会资源的整合协调者,通过统一接入和身份识别,实现社区信息和服务的便捷获取,提升居民生活质量,促进社区和谐。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值