在Spring中使用AOP实现日志功能

步骤:
1.创建一个动态WEB项目;
2.导入以下十个jar包:

  • com.springsource.net.sf.cglib -2.2.0.jar
  • com.springsource.org.aopalliance-1.0.0 .jar
  • com.springsource.org.aspectj.weaver-1.6.8 .RELEASE.jar
  • commons-logging-1.1.3. jar
  • spring-aop-4.0.0.RELEASE.jar
  • spring-aspects-4.0.0.RELEASE.jar
  • spring-beans-4.0.0.RELEASE.jar
  • spring-context-4.0.0.RELEASE.jar
  • spring-core-4.0.0.RELEASE.jar
  • spring-expression-4.0.0.RELEASE. jar

使用注解的方式实现AOP

这里写图片描述
3.开启基于注解的AOP功能
在配置文件applictionContext.xml中加入

<context:component-scan base-package="com.neuedu.aop"/>
    <!-- 开启基于注解的AOP功能 -->
    <aop:aspectj-autoproxy/>

4.声明一个切面类,并把这个切面类加入到IOC容器中

@Aspect//表示这是一个切面类
@Component//加入IOC容器
public class LogAspect {}

5.在切面类中声明通知方法
[1]前置通知:@Before
[2]返回通知:@AfterReturning
[3]异常通知:@AfterThrowing
[4]后置通知:@After
[5]环绕通知:@Around :环绕通知是前面四个通知的集合体!

        @Aspect//表示这是一个切面类
        @Component//将本类对象加入到IOC容器中!
        public class LogAspect {
            @Before(value="execution(public int com.neuedu.aop.target.MathCalculatorImpl.add(int, int))")
            public void showBeginLog(){
                System.out.println("AOP日志开始");
            }
            @After(value="execution(public int com.neuedu.aop.target.MathCalculatorImpl.add(int, int))")
            public void showReturnLog(){
                System.out.println("AOP方法返回");
            }
            @AfterThrowing(value="execution(public int com.neuedu.aop.target.MathCalculatorImpl.add(int, int))")
            public void showExceptionLog(){
                System.out.println("AOP方法异常");
            }
            @AfterReturning(value="execution(public int com.neuedu.aop.target.MathCalculatorImpl.add(int, int))")
            public void showAfterLog(){
                System.out.println("AOP方法结束");
            }
        }

6.被代理的对象也需要加入IOC容器

        @Component//加入IOC容器
        public class MathCalculatorImpl {

            public int add(int i,int j){
                int result = i+j;
                return result;
            }
            public int sub(int i,int j){
                int result = i-j;
                return result;
            }
            public int multi(int i,int j){
                int result = i*j;
                return result;
            }
            public int divide(int i,int j){
                int result = i/j;
                return result;
            }
        }

方法二 统一声明切入点表达式

//统一式切入点
    @Pointcut(value="execution(public * com.neuedu.aop.Mycomputer.*(..))")
    public void show(){

    }
    @Before(value="show()")
    public void showBeginLog(JoinPoint point){
        Object[] args = point.getArgs();
        //获取签名
        Signature signature = point.getSignature();
        String name = signature.getName();
        List<Object> aslist=Arrays.asList(args);

        System.out.println(aslist);

        args.toString();
        System.out.println("方法名:"+name);
        System.out.println("日志开始");
    }
    @After(value="show()")
    public void showAfterLog(){
        System.out.println("日志正常结束");
    }
    @AfterThrowing(value="show()" ,throwing= "throwable")
    public void showException(JoinPoint joinPoint, Throwable throwable){
        System.out.println(throwable.getMessage());
        System.out.println("日志出现异常");
    }
    @AfterReturning(value="show()",returning="result")
    public void showFinnalyLog(JoinPoint point,Object result){
        System.out.println("目标方法的返回值为:"+result);
        System.out.println("日志最终结束");
    }

方法三 环绕通知实现

@Around(value="execution(public * com.neuedu.aop.Mycomputer.*(..))")
    public Object showLog(ProceedingJoinPoint point){
        Object[] args = point.getArgs();
        List<Object> asList=Arrays.asList(args);
        Object result=null;
        Signature signature = point.getSignature();
        String name = signature.getName();
        try{
            try{
            //前置通知@Before
            System.out.println("目标开始:方法名为"+name+"参数名为"+asList);
            result=point.proceed(args);
            }
            finally{
                //后置通知@After
                System.out.println("目标后置结束");
            }
            //返回通知@AfterReturning
            System.out.println("目标结束"+result);
    }catch(Throwable e){
        //异常通知@AfterThrowing
        System.out.println("有异常:异常为"+e.getMessage());
    }
    return result;
    }

使用xml文件配置的方式实现AOP

<bean id="mycomputer" class="com.neuedu.aop.Mycomputer"/>
    <bean id="nozhujieAspect" class="com.neuedu.aop.NozhujieAspect"/>
    <bean id="tscAapect" class="com.neuedu.aop.TscAapect"/>
    <aop:config >
        <aop:pointcut expression="execution(public * com.neuedu.aop.Mycomputer.*(..))" id="mypiontcut"/>
        <aop:aspect ref="nozhujieAspect" order="20">
            <aop:before method="showBeginLog" pointcut-ref="mypiontcut"/>
            <aop:after method="showAfterLog" pointcut-ref="mypiontcut"/>
            <aop:after-throwing method="showException" pointcut-ref="mypiontcut" throwing="ex"/>
            <aop:after-returning method="showFinnalyLog" pointcut-ref="mypiontcut" returning="result"/>
        </aop:aspect>
        <aop:aspect ref="tscAapect" order="10">
            <aop:around method="showLog" pointcut-ref="mypiontcut"/>
        </aop:aspect>
    </aop:config>

需要知道的是:事务的管理是和AOP是有很大关系的,即声明式事务的底层是用事务实现的!

原文地址:https://www.cnblogs.com/mazhitao/p/7454875.html