Spring学习之路(4)——AOP

为什么要使用AOP?

AOP是面向对象编程(OOP)的一种补充,目前已成为一种比较成熟的编程方式。

在传统的业务处理代码中,通常都会进行事务处理、日志记录等操作。虽然使用OOP可以通过组合或者继承的方式来达到代码的重用,但如果要实现某个功能(如日志记录),同样的代码仍然会分散到各个方法中。这样,如果想要关闭某个功能,或者对其进行修改,就必须要修改所有的相关方法。这不但增加了开发人员的工作量,而且提高了代码的出错率。

为了解决这一问题,AOP思想随之产生。AOP采用横向抽取机制,将分散在各个方法的重复代码提取出来,然后在程序编译或运行时,再将这些提取出来的代码应用到需要执行的地方。这种采用横向抽取机制的方式,采用传统的OOP思想显然是无法办到的,因为OOP只能实现父子关系的纵向的重用。虽然AOP是一种新的编程思想,但却不是OOP的替代品,它只是OOP的延伸和补充。

AOP的使用,使开发人员在编写业务逻辑时可以专心于核心业务,而不必过多地关注于其他业务逻辑的实现这不但提高了开发效率,而且增强了代码的可维护性。

 AOP中的名词概念

Aspect(切面):指横切性关注点的抽象即为切面,与类相似,只是两者的关注点不同,类是对物体特征的抽象,而切面是对横切面关注点的抽象。

JoinPoint(连接点):连接点是指那些被拦截到的点,spring中这些点指的是方法。

Pointcut(切入点):切入点是指我们要对那些JoinPoint进行拦截的定义。

Advice(通知):通知是指拦截到JoinPoint之后要做的事情,分为前置通知、后置通知、异常通知,最终通知、环绕通知。

前置通知和后置通知一个是在连接点之前执行,一个是在连接点退出的时候执行。异常通知是方法抛出异常退出时执行的逻辑。环绕通知是包围连接点退出的时候执行的逻辑。

AOP注解方式编程的步骤

  1. 定义一个切面类    @Aspect注解
  2. 定义@Pointcut切点,即定义一个方法,指定拦截项目中的那些方法
  3. 定义五中类型中的哪一种通知,即定义了一个方法,表示切点拦截到了方法后,执行什么功能
  4. beans.xml中添加<aop:aspectj-autoproxy></aop:aspectj-autoproxy>标签,支持aop的注解
package cn.sdut.aop;

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;

/**
 * 切面类
 * @author DELL
 *
 */

@Component //组件注解
@Aspect //注解切面类
public class AspectLog {

	//注解切入点作用于cn.sdut.service包下所有的类的方法
	@Pointcut(value="execution(* cn.sdut.service.*.*(..))")
	private void pointCut() {
		
	}
	
	//注解前置通知
	@Before(value="pointCut()")
	public void beforeLog(JoinPoint joinPoint) {
		System.out.println(joinPoint.getSignature().getDeclaringTypeName()+"."
	+joinPoint.getSignature().getName()+" is called.. before");
	}
	
	//注解后置通知
	@After(value="pointCut()")
	public void afterLog(JoinPoint joinPoint) {
		System.out.println(joinPoint.getSignature().getDeclaringTypeName()+"."
	+joinPoint.getSignature().getName()+" is called.. after");
	}
	
	//返回注解通知
	@AfterReturning(value="pointCut()")
	public void afterReturningLog(JoinPoint joinPoint) {
		System.out.println(joinPoint.getSignature().getDeclaringTypeName()+"."+
	joinPoint.getSignature().getName()+" ar is called.. return");
	}
	
	//环绕通知
	@Around(value="pointCut()")
	public Object AroundLog(ProceedingJoinPoint point) throws Throwable {
		System.out.println(point.getSignature().getDeclaringTypeName()+"."+
				point.getSignature().getName()+" ar is called.. start");
		Object object = point.proceed();
		System.out.println(point.getSignature().getDeclaringTypeName()+"."+
				point.getSignature().getName()+" ar is called.. end");
		return object;
	}
	
	//异常通知
	@AfterThrowing(value="pointCut()")
	public void afterThrowingLog(JoinPoint joinPoint) {
		System.out.println(joinPoint.getSignature().getDeclaringTypeName()+"."+
	joinPoint.getSignature().getName()+" ar is called.. throwing");
	}
}

AOP的xml方式配置

  • 定义切面类,编写切面类中的方法
  • beans.xml中配置aop信息

<aop:config>
                <aop:aspect id="myAspect" ref="aspectLog">
                    <aop:pointcut id="mypointcut" expression="execution(* cn.sdut.dao.*.*(..))" />
                    <aop:before method="beforeLog" pointcut-ref="mypointcut"/>
                    <aop:after method="afterLog" pointcut-ref="mypointcut"/>
                    <aop:after-returning method="afterReturningLog" pointcut-ref="mypointcut"/>
                    <aop:around method="aroundLog" pointcut-ref="mypointcut"/>
                    <aop:after-throwing method="afterThrowingLog" pointcut-ref="mypointcut"/>
                </aop:aspect>
            </aop:config>

 

ref指向的是切面类首字母小写 。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值