Spring Aop应用

本文介绍了一个具体的Java AOP实现案例,通过Spring框架的AspectJ支持,结合Shiro权限框架,对Web应用的请求进行前置、后置、异常等通知处理,并记录详细的日志信息。
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest;
 
import org.apache.log4j.Logger;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
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.stereotype.Component;
 
/**
 * 类说明:系统服务组件Aspect切面Bean
 * 
 * @author 作者 lwz
 * @version 
 */
@Component
@Aspect
public class ServiceAspect {
 
	private static final Logger log = Logger.getLogger(ServiceAspect.class);
 
	// 配置切入点,该方法无方法体,主要为方便同类中其他方法使用此处配置的切入点
	@Pointcut("execution(* com.ultrapower.rw.web.ows.controller.app..*(..))")
	public void aspect() {
	}
 
	/*
	 * 配置前置通知,使用在方法aspect()上注册的切入点 同时接受JoinPoint切入点对象,可以没有该参数
	 */
	@Before("aspect()")
	public void before(JoinPoint joinPoint) {
		Object[] args = joinPoint.getArgs();// 获得目标方法的参数
		String name = joinPoint.getSignature().getName();// 获得目标方法名
		log.info("<=============" + name + "方法--AOP 前置通知=============>");
		if (args != null && args.length > 0
				&& args[0].getClass() == ShiroHttpServletRequest.class) {
			HttpServletRequest request = (HttpServletRequest) joinPoint
					.getArgs()[0];
			String requestURI = request.getRequestURI();
			@SuppressWarnings("unchecked")
			Map<String, String> parameterMap = request.getParameterMap();
			StringBuilder paramStr = new StringBuilder();
			for (Map.Entry<String, String> param : parameterMap.entrySet()) {
				paramStr.append(param.getKey()).append("=")
						.append(param.getValue());
			}
			if (paramStr.length() > 0) {
				requestURI = requestURI + "?" + paramStr.toString();
			}
			log.info(name + " 方法请求路径与参数:" + requestURI);
		}
 
	}
 
	// 配置后置通知,使用在方法aspect()上注册的切入点
	@After("aspect()")
	public void after(JoinPoint joinPoint) {
		if (log.isInfoEnabled()) {
			String name = joinPoint.getSignature().getName();// 获得目标方法名
			log.info("<=============" + name + "方法--AOP 后置通知=============>");
		}
	}
 
	// 配置环绕通知,使用在方法aspect()上注册的切入点
	@Around("aspect()")
	public Object around(ProceedingJoinPoint joinPoint) {
		String name = joinPoint.getSignature().getName();// 获得目标方法名
		log.info("<=============" + name + "方法--AOP 环绕通知=============>");
		long start = System.currentTimeMillis();
		Object result = null;
		try {
			result = joinPoint.proceed();
			long end = System.currentTimeMillis();
			if (log.isInfoEnabled()) {
				log.info("around " + joinPoint + "\tUse time : "
						+ (end - start) + " ms!");
			}
		} catch (Throwable e) {
			long end = System.currentTimeMillis();
			if (log.isInfoEnabled()) {
				log.info("around " + joinPoint + "\tUse time : "
						+ (end - start) + " ms with exception : "
						+ e.getMessage());
			}
		}
		return result;
	}
 
	// 配置后置返回通知,使用在方法aspect()上注册的切入点
	@AfterReturning(pointcut = "aspect()", returning = "result")
	public void afterReturn(JoinPoint joinPoint, Object result) {
		String name = joinPoint.getSignature().getName();// 获得目标方法名
		log.info("<=============" + name + "方法--AOP 后置返回通知=============>");
		log.info(name + "方法返回参数:" + result);
	}
 
	// 配置抛出异常后通知,使用在方法aspect()上注册的切入点
	@AfterThrowing(pointcut = "aspect()", throwing = "ex")
	public void afterThrow(JoinPoint joinPoint, Exception ex) {
		String name = joinPoint.getSignature().getName();// 获得目标方法名
		log.info("<=============" + name + "方法--AOP 异常后通知=============>");
		log.info(name + "方法抛出异常为:" + "\t" + ex.getMessage());
	}
 
}

 

Spring AOPSpring框架中应用AOP(面向切面编程)思想的一种方式。它使用动态代理技术来实现。默认情况下,Spring会根据被代理对象是否实现接口来选择使用JDK动态代理还是CGLIB动态代理。当被代理对象没有实现任何接口时,Spring会选择CGLIB。当被代理对象实现了接口,Spring会选择JDK官方的代理技术。但是我们也可以通过配置的方式,让Spring强制使用CGLIB动态代理。 Spring AOP的配置方式有多种,包括XML模式、XML注解模式和纯注解模式。通过这些配置方式,我们可以将AOP的切面逻辑织入到我们的业务代码中,实现各种功能,比如事务管理等。 在Spring中,事务管理是AOP的一种常见应用Spring提供了多种事务管理器的实现,例如DataSourceTransactionManager和HibernateTransactionManager等。这些事务管理器实现了Spring的事务管理器核心接口,负责提供具体的事务实现策略。我们可以根据需要选择合适的事务管理器来管理数据库操作或其他事务。同时,Spring也提供了基于注解的声明式事务配置,通过在代码中使用注解来实现事务管理。 总之,Spring AOP可以应用在各种场景中,包括但不限于事务管理。通过AOP的切面编程思想,我们可以将一些横切逻辑代码(比如事务管理、日志记录等)与业务代码解耦,提高代码的可维护性和可扩展性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Spring AOP 应用](https://blog.youkuaiyun.com/weixin_44152160/article/details/125360176)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值