Spring aop 实战与详解

本文通过实战演示了Spring AOP的使用方法,包括基于@Aspect注解的AspectJ风格的AOP实现,以及如何在登录和服务注册场景下应用Before、After-returning、After-throwing等通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring aop 中Aspect的详解与实战例子

Spring aop的的原理:

面向切面的编程,即在预编译和运行期间动态代理方式在不改变现有代码情况下实现某些功能;

Spring aop实现四种方式:

1.经典的基于AOP代理 2.@Aspect注解驱动的界面3.纯POJO切面4.注入式Aspect切面

Spring aop支持5种类型的通知:

1.Before(前)  org.apringframework.aop.MethodBeforeAdvice
2.After-returning(返回后) org.springframework.aop.AfterReturningAdvice
3.After-throwing(抛出后) org.springframework.aop.ThrowsAdvice
4.Arround(周围) org.aopaliance.intercept.MethodInterceptor
5.Introduction(引入) org.springframework.aop.IntroductionInterceptor

下面对Spring aop 中的Aspect进行实战

首先是2个接口类 
package com.zjdelai.emall.horse.web.action.test.aop;


public interface ILoginService {

public boolean loginOut(String userName);

public boolean loginIn(String userName, String password);

}

package com.zjdelai.emall.horse.web.action.test.aop;


public interface IRegisterService {

    public void Register(String userName, String password);
    
}

上面2个接口的实现类
package com.zjdelai.emall.horse.web.action.test.aop.impl;

import org.springframework.stereotype.Service;

import com.zjdelai.emall.horse.web.action.test.aop.ILoginService;

@Service
public class LoginServiceImpl implements ILoginService{

@Override
public boolean loginOut(String userName) {
// TODO Auto-generated method stub
System.out.println("退出成功:login:" + userName);
return false;
}

@Override
public boolean loginIn(String userName, String password) {
// TODO Auto-generated method stub
System.out.println("登录成功:login:" + userName + "," + password);
return false;
}

}

package com.zjdelai.emall.horse.web.action.test.aop.impl;

import org.springframework.stereotype.Service;

import com.zjdelai.emall.horse.web.action.test.aop.IRegisterService;

@Service
public class RegisterServiceImpl implements IRegisterService{


@Override
public void Register(String userName, String password) {
// TODO Auto-generated method stub
throw new RuntimeException("优惠券未绑定,强制使用");
}

}

3对上述2个进行注入的类
package com.zjdelai.emall.horse.web.action.test.aop;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;


@Aspect
public class LogAspect {


    /**
     * 此方法记录调用前执行
     * @param jp
     * @param retVal
     */
@Before("execution(* com.zjdelai.emall.horse.web.action.test.aop.impl.*.*(..))")
public void beforeLog(JoinPoint jp){
System.out.println("此方法记录调用前执行------");
StringBuffer sb = new StringBuffer();
        String className = jp.getTarget().getClass().getName();//获取目标对象对应的类名
        String methodName = jp.getSignature().getName();//获取目标对象上正在执行的方法名
        sb.append("\r\n您所调用的类名:"+className+";\r\n");
sb.append("\r\n您所调用的方法:"+methodName+";\r\n");
Object[] parames = jp.getArgs();
for(int i=0;i<parames.length;i++){
sb.append("参数名:").append(parames[i]==null?"null":parames[i].toString());
}
sb.append(";\r\n");
System.out.println(sb.toString());
}

/**
     * 记录接口调用后return执行
     * @param jp
     * @param retVal
     */
@AfterReturning(pointcut="execution(* com.zjdelai.emall.horse.web.action.test.aop.impl.*.*(..))",returning="retVal")
public void afterReturnLog(JoinPoint jp,Object retVal){
System.out.println("记录接口调用后return执行");
StringBuffer sb = new StringBuffer();
        String className = jp.getTarget().getClass().getName();//获取目标对象对应的类名
        String methodName = jp.getSignature().getName();//获取目标对象上正在执行的方法名
        sb.append("\r\n您所调用的类名:"+className+";\r\n");
sb.append("\r\n您所调用的方法:"+methodName+";\r\n");
Object[] parames = jp.getArgs();
for(int i=0;i<parames.length;i++){
sb.append("参数名:").append(parames[i]==null?"null":parames[i].toString());
}
sb.append("\r\n您所调用的返回值:"+jp.getSignature().toString()+";\r\n");
System.out.println(sb.toString());
}

/**
     * 此方法记录 调用后执行
     * @param jp
     * @param retVal
     */
@After("execution(* com.zjdelai.emall.horse.web.action.test.aop.impl.*.*(..))")
public void afterLog(JoinPoint jp){
System.out.println("此方法记录调用后执行");
StringBuffer sb = new StringBuffer();
        String className = jp.getTarget().getClass().getName();//获取目标对象对应的类名     
        String methodName = jp.getSignature().getName();//获取目标对象上正在执行的方法名     
        sb.append("\r\n您所调用的类名:"+className+";\r\n");
sb.append("\r\n您所调用的方法:"+methodName+";\r\n");
Object[] parames = jp.getArgs();
for(int i=0;i<parames.length;i++){
sb.append("参数名:").append(parames[i]==null?"null":parames[i].toString());
}
sb.append(";\r\n");
System.out.println(sb.toString());
}

/**
     * 此方法记录异常执行
     * @param jp
     * @param retVal
     */
@AfterThrowing("execution(* com.zjdelai.emall.horse.web.action.test.aop.impl.*.*(..))")
public void afterThrowing(JoinPoint jp){
System.out.println("此方法记录异常执行");
StringBuffer sb = new StringBuffer();
String className = jp.getTarget().getClass().getName();//获取目标对象对应的类名     
        String methodName = jp.getSignature().getName();//获取目标对象上正在执行的方法名     
        sb.append("\r\n您所调用的类名:"+className+";\r\n");
sb.append("\r\n您所调用的方法:"+methodName+";\r\n");
Object[] parames = jp.getArgs();
for(int i=0;i<parames.length;i++){
sb.append("参数名:").append(parames[i]==null?"null":parames[i].toString());
}
sb.append(";\r\n");
System.out.println(sb.toString());
}
}

4下面对上述几个进行配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"   
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
 xmlns:aop="http://www.springframework.org/schema/aop"   
 xmlns:context="http://www.springframework.org/schema/context"   
 xmlns:p="http://www.springframework.org/schema/p"   
 xmlns:tx="http://www.springframework.org/schema/tx"     
 xmlns:cache="http://www.springframework.org/schema/cache"
 xsi:schemaLocation="http://www.springframework.org/schema/beans    
  http://www.springframework.org/schema/beans/spring-beans.xsd   
  http://www.springframework.org/schema/aop    
  http://www.springframework.org/schema/aop/spring-aop-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/tx    
  http://www.springframework.org/schema/task/spring-task-3.0.xsd
  http://www.springframework.org/schema/cache    
  http://www.springframework.org/schema/cache/spring-cache.xsd" default-autowire="byName">

<bean id="loginService" class="com.zjdelai.emall.horse.web.action.test.aop.impl.LoginServiceImpl"></bean>
<bean id="registerService" class="com.zjdelai.emall.horse.web.action.test.aop.impl.RegisterServiceImpl"></bean>

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="LogAspect" class="com.zjdelai.emall.horse.web.action.test.aop.LogAspect"></bean>

</beans>

5测试类

package com.zjdelai.emall.horse.web.action.content;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


import com.zjdelai.emall.cms.remoting.service.newscontent.INewsContentService;
import com.zjdelai.emall.horse.web.action.BaseHorseAction;
import com.zjdelai.emall.horse.web.action.test.aop.ILoginService;
import com.zjdelai.emall.horse.web.action.test.aop.IRegisterService;




@Controller
public class NewsAction extends BaseHorseAction {

@Autowired
INewsContentService newsContentService;

@Autowired
ILoginService loginService;

@Autowired
IRegisterService registerService;


    public void setNewsContentService(INewsContentService newsContentService) {
this.newsContentService = newsContentService;
}


public void setLoginService(ILoginService loginService) {
this.loginService = loginService;
}


public void setRegisterService(IRegisterService registerService) {
this.registerService = registerService;
}


@RequestMapping("/news/list.htm")
    public void testAop() {
loginService.loginIn("李俊", "123321");
loginService.loginOut("李俊");
registerService.Register("李俊", "123321");
    }

}

6.运行结果
此方法记录调用前执行------


您所调用的类名:com.zjdelai.emall.horse.web.action.test.aop.impl.LoginServiceImpl;


您所调用的方法:loginIn;
参数名:李俊参数名:123321;


登录成功:login:李俊,123321
记录接口调用后return执行


您所调用的类名:com.zjdelai.emall.horse.web.action.test.aop.impl.LoginServiceImpl;


您所调用的方法:loginIn;
参数名:李俊参数名:123321
您所调用的返回值:boolean com.zjdelai.emall.horse.web.action.test.aop.ILoginService.loginIn(String,String);


此方法记录调用后执行


您所调用的类名:com.zjdelai.emall.horse.web.action.test.aop.impl.LoginServiceImpl;


您所调用的方法:loginIn;
参数名:李俊参数名:123321;


此方法记录调用前执行------


您所调用的类名:com.zjdelai.emall.horse.web.action.test.aop.impl.LoginServiceImpl;


您所调用的方法:loginOut;
参数名:李俊;


退出成功:login:李俊
记录接口调用后return执行


您所调用的类名:com.zjdelai.emall.horse.web.action.test.aop.impl.LoginServiceImpl;


您所调用的方法:loginOut;
参数名:李俊
您所调用的返回值:boolean com.zjdelai.emall.horse.web.action.test.aop.ILoginService.loginOut(String);


此方法记录调用后执行


您所调用的类名:com.zjdelai.emall.horse.web.action.test.aop.impl.LoginServiceImpl;


您所调用的方法:loginOut;
参数名:李俊;


此方法记录调用前执行------


您所调用的类名:com.zjdelai.emall.horse.web.action.test.aop.impl.RegisterServiceImpl;


您所调用的方法:Register;
参数名:李俊参数名:123321;


此方法记录调用后执行


您所调用的类名:com.zjdelai.emall.horse.web.action.test.aop.impl.RegisterServiceImpl;


您所调用的方法:Register;
参数名:李俊参数名:123321;


此方法记录异常执行


您所调用的类名:com.zjdelai.emall.horse.web.action.test.aop.impl.RegisterServiceImpl;


您所调用的方法:Register;
参数名:李俊参数名:123321;

2015-09-16 10:47:28,878 ERROR [com.zjdelai.emall.horse.spring.mvc.servlet.LoggerHandlerExceptionResolver] - exception is handled by HandlerExceptionResolver
java.lang.RuntimeException: 优惠券未绑定,强制使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值