Spring学习日记(二)AOP的深入操作

上次的AOP操作简单,但对初学者而言,删繁就简地体现了aop的设计思想。但有些过于简化了,本次将把参数带入到aop的操作中。

一、前置通知中含参数

1、修改切面处理类:改写serviceBefore(),使其含有参数

  public void serviceBefore2(Object arg){
	  System.out.println("【AOP切面】执行日志记录操作。参数="+ arg);
  }

2、修改配置文件:切入点表达式

	<aop:config>
	    <aop:pointcut expression="execution(* cn.mldn..*.*(..)))" id="pointcut"/>
	    <aop:aspect ref="serviceAspect">
	    <!-- 重点看pointcut表达式,以及参数的传递 -->	    
	        <aop:before method="serviceBefore2" pointcut="execution(* cn.mldn..*.*(..)) and args(vo))" arg-names="vo"/>
	        <aop:after method="serviceAfter" pointcut-ref="pointcut"/>
	    </aop:aspect>
	</aop:config>

3、运行结果

【AOP切面】执行日志记录操作。参数=Member [mid=mldn, name=你好]
【数据层调用】member=Member [mid=mldn, name=你好]
【AOP切面】执行事务处理操作
false

二、针对结果拦截

1、修改切面处理类:改写serviceAfter(),使其含有参数

  public void serviceAfterReturning(Object val){
	  System.out.println("【AOP切面】操作完成,返回结果,参数为:"+val);
  }

2、修改配置文件:切入点表达式

	<aop:config>
	    <aop:pointcut expression="execution(* cn.mldn..*.*(..)))" id="pointcut"/>
	    <aop:aspect ref="serviceAspect">    
	        <aop:before method="serviceBefore2" pointcut="execution(* cn.mldn..*.*(..)) and args(vo))" arg-names="vo"/>
	        <!-- 看这里 -->	    
	        <aop:after-returning method="serviceAfterReturning" pointcut-ref="pointcut" returning="haha" arg-names="haha"/>
	    </aop:aspect>
	</aop:config>

3、运行结果

【AOP切面】执行日志记录操作。参数=Member [mid=mldn, name=你好]
【数据层调用】member=Member [mid=mldn, name=你好]
【AOP切面】操作完成,返回结果,参数为:false
false

 

三、抛出异常拦截

1、修改MemberServiceImpl.class

public class MemberServiceImpl implements IMemberService {
	@Override
	public boolean insert(Member vo) {
		throw new NullPointerException("Exception occured");
	}

}

2、修改切面处理类

  public void  serviceAfterThrowing(Exception exp) {
	System.out.println("【aop切面】操作出现异常,异常为:"+exp);
}

3、修改配置文件:切入点表达式

	<aop:config>
	    <aop:pointcut expression="execution(* cn.mldn..*.*(..)))" id="pointcut"/>
	    <aop:aspect ref="serviceAspect">
	        <aop:before method="serviceBefore2" pointcut="execution(* cn.mldn..*.*(..)) and args(vo))" arg-names="vo"/>
	        <aop:after-returning method="serviceAfterReturning" pointcut-ref="pointcut" returning="haha" arg-names="haha"/>
            <!--看这里-->
	        <aop:after-throwing method="serviceAfterThrowing" pointcut="execution(* cn.mldn..*.*(..)))" arg-names="exp" throwing="exp"/>  
	    </aop:aspect>
	</aop:config>

4、运行结果

 

四、环绕通知

    环绕通知:一个方法处理所有操作,这种操作更像代理机构,但注意:要考虑有返回值的情况!!!

1、修改切面处理类:增加环绕处理方法

  public Object serviceAround(ProceedingJoinPoint point) throws Throwable{
	System.out.println("【AOP切面】数据层方法调用前,参数"+Arrays.toString(point.getArgs()));  
	Member vo=new Member();
	vo.setMid("hello");
	vo.setName("world");
	Object retVal=point.proceed(new Object[] { vo });
	System.out.println("【AOP切面】数据层方法调用之后,返回值:"+retVal);	
	return true;
  }

2、修改配置文件:切入点表达式

	<aop:config>
	    <aop:pointcut expression="execution(* cn.mldn..*.*(..)))" id="pointcut"/>
	    <aop:aspect ref="serviceAspect">
	    <aop:around method="serviceAround" pointcut-ref="pointcut"/> 
	    </aop:aspect>
	</aop:config>
	

3、结果:可以说是很强大了!

对传入参数和返回结果可以修改!但这样不好,不建议这么做。

 

五、通过Annotation配置简化AOP的操作

1、修改配置文件

其他都可以删掉了~

<aop:aspectj-autoproxy/>

2、修改切面处理类

     加了很多@XXX

@Component
@Aspect
public class ServiceAspect2 {
  @Before(value="execution(* cn.mldn..*.*(..)))")
  public void serviceBefore(){
	  System.out.println("【AOP切面】执行日志记录操作");
  }
  @Before(value="execution(* cn.mldn..*.*(..)) and args(param)",argNames="param")
  public void serviceBefore2(Object arg){
	  System.out.println("【AOP切面】执行日志记录操作。参数="+ arg);
  }
  @After(value="execution(* cn.mldn..*.*(..)))")
  public void serviceAfter(){
	  System.out.println("【AOP切面】执行事务处理操作");
  }
  @AfterReturning(value="execution(* cn.mldn..*.*(..)))",argNames="ret",returning="ret")
  public void serviceAfterReturning(Object val){
	  System.out.println("【AOP切面】操作完成,返回结果,参数为:"+val);
  }
  @AfterThrowing(value="execution(* cn.mldn..*.*(..)))",argNames="e",throwing="e")
  public void  serviceAfterThrowing(Exception exp) {
	System.out.println("【aop切面】操作出现异常,异常为:"+exp);
}
  @Around(value="execution(* cn.mldn..*.*(..)))")
  public Object serviceAround(ProceedingJoinPoint point) throws Throwable{
	System.out.println("【AOP切面】数据层方法调用前,参数"+Arrays.toString(point.getArgs()));  
	Member vo=new Member();
	vo.setMid("hello");
	vo.setName("world");
	Object retVal=point.proceed(new Object[] { vo });
	System.out.println("【AOP切面】数据层方法调用之后,返回值:"+retVal);	
	return true;
  }

3、运行结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值