Spring AOP阐述

什么是AOP?

         AOP,即Aspect Oriented Programming(面向切面编程)。下面举例说明:

业务编程

        用户增删该查:

package org.test.aop;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/** 用户管理业务控制器 */
public class UserAction {

	private static Logger logger = LogManager.getLogger(UserAction.class);
	
	// 新增用户
	public void addUser() {
		logger.info("addUser");
		throw new RuntimeException("这是特意抛出的异常信息!");
	}

	// 删除用户
	public void delUser() {
		logger.info("delUser");
	}
	
	// 修改用户
	public void modiUser() {
		logger.info("modiUser");
	}

	// 查询用户
	public void loadUser() {
		logger.info("loadUser");
	}

}

现在想对增删该查操作前后打印日志,以跟踪业务处理过程,该业务场景就需要AOP来处理,在不侵入业务逻辑的前提下。

AOP切面编程

        日志切面:

package org.test.aop;

/** 日志切面 */
public class LogAspectJ {
	// 取得日志记录器Logger
	private static Logger logger = LogManager.getLogger(LogAspectJ.class);

	private void anyMethod() {
		
	}
	
	// 前置通知
	public void myBeforeAdvice(JoinPoint joinpoint) {
		String classAndMethod = joinpoint.getTarget().getClass().getName()
				+ "类的" + joinpoint.getSignature().getName();
		logger.info("前置通知:" + classAndMethod + "方法开始执行!");
	}

	// 后置通知
	public void myAfterReturningAdvice(JoinPoint joinpoint) {
		String classAndMethod = joinpoint.getTarget().getClass().getName()
				+ "类的" + joinpoint.getSignature().getName();
		logger.info("后置通知:" + classAndMethod + "方法执行正常结束!");
	}

	// 异常通知
	public void myAfterThrowingAdvice(JoinPoint joinpoint, Exception e) {
		String classAndMethod = joinpoint.getTarget().getClass().getName()
				+ "类的" + joinpoint.getSignature().getName();
		logger.info("异常通知:" + classAndMethod + "方法抛出异常:  " + e.getMessage());
	}

	// 最终通知
	public void myAfterAdvice(JoinPoint joinpoint) {
		String classAndMethod = joinpoint.getTarget().getClass().getName()
				+ "类的" + joinpoint.getSignature().getName();
		logger.info("最终通知:" + classAndMethod + "方法执行结束!");
	}

	// 做环绕通知
	public Object myAroundAdvice(ProceedingJoinPoint pjp) throws Throwable {  
		long begintime = System.currentTimeMillis();//记下开始时间  
		//传递给连接点对象进行接力处理  
		Object result=pjp.proceed();  
		long endtime = System.currentTimeMillis();//记下结束时间  
		String classAndMethod = pjp.getTarget().getClass().getName()+  
		"类的"+pjp.getSignature().getName();  
		logger.info("环绕通知:"+classAndMethod+"方法执行结束, 耗时"+(endtime-begintime)+"毫秒!");  
		return result;  
	}
}

AOP配置

        将业务编程、切面编程关联:

在Spring的配置文件中:

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
						http://www.springframework.org/schema/context  
						http://www.springframework.org/schema/context/spring-context-3.0.xsd
						http://www.springframework.org/schema/aop
						http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
  	<bean id="userAction" class="org.test.aop.UserAction"/>
	
	// 日志切面bean
  	<bean id="logAspectJ" class="org.test.aop.LogAspectJ"/> 
	<aop:config>
		// 定义日志切面
		<aop:aspect id="logaop" ref="logAspectJ">
			// 日志切面所关注业务的点,即expression中匹配的哪些类、哪些方法
	    	<aop:pointcut id="logpointcut" expression="execution(* org.test.aop.UserAction.*(..))"/>
			// 在所关注的点上,进行的切面动作,即各类通知
	    	<aop:before pointcut-ref="logpointcut" method="myBeforeAdvice"/>  // 前置通知
			<aop:after-returning pointcut-ref="logpointcut" method="myAfterReturningAdvice"/>  // 后置通知 
			<aop:after-throwing pointcut-ref="logpointcut" method="myAfterThrowingAdvice" throwing="e"/> // 异常通知    
			<aop:after pointcut-ref="logpointcut" method="myAfterAdvice"/> // 最终通知   
			<aop:around pointcut-ref="logpointcut" method="myAroundAdvice"/> // 环绕通知
	    </aop:aspect>
	</aop:config>  

</beans>  

AOP作用结果

userAction.addUser()运行结果:

2016-11-23 16:01:00,878 main INFO Log4j appears to be running in a Servlet environment, but there's no log4j-web module available. If you want better web container support, please add the log4j-web JAR to your web archive or server lib directory.
16:01:01.073 INFO  org.test.aop.LogAspectJ myBeforeAdvice 27 main - 前置通知:org.test.aop.UserAction类的addUser方法开始执行!
16:01:01.088 INFO  org.test.aop.UserAction addUser 13 main - addUser
16:01:01.089 INFO  org.test.aop.LogAspectJ myAfterAdvice 51 main - 最终通知:org.test.aop.UserAction类的addUser方法执行结束!
16:01:01.089 INFO  org.test.aop.LogAspectJ myAfterThrowingAdvice 43 main - 异常通知:org.test.aop.UserAction类的addUser方法抛出异常:  这是特意抛出的异常信息!

userAction.delUser()运行结果:

2016-11-23 15:02:53,971 main INFO Log4j appears to be running in a Servlet environment, but there's no log4j-web module available. If you want better web container support, please add the log4j-web JAR to your web archive or server lib directory.
15:02:54.165 INFO  org.test.aop.LogAspectJ myBeforeAdvice 27 main - 前置通知:org.test.aop.UserAction类的delUser方法开始执行!
15:02:54.179 INFO  org.test.aop.UserAction delUser 19 main - delUser
15:02:54.180 INFO  org.test.aop.LogAspectJ myAroundAdvice 63 main - 环绕通知:org.test.aop.UserAction类的delUser方法执行结束, 耗时14毫秒!
15:02:54.180 INFO  org.test.aop.LogAspectJ myAfterAdvice 51 main - 最终通知:org.test.aop.UserAction类的delUser方法执行结束!
15:02:54.180 INFO  org.test.aop.LogAspectJ myAfterReturningAdvice 35 main - 后置通知:org.test.aop.UserAction类的delUser方法执行正常结束!

       在日志切面中,Spring AOP的作用就是,将日志切面中的各类通知作用在其所关注的业务点,以打印相关日志,跟踪业务处理过程。需要注意的是,业务编程和AOP编程是解耦的。

这里只是AOP应用的一个业务场景而已,以此向其他业务场景类推,但原理和流程一样,面向切面编程很形象的阐述了AOP。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值