• 在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是有很大关系的,即声明式事务的底层是用事务实现的!

  • 相关阅读:
    二叉搜索树的第k个结点
    序列化二叉树
    把二叉树打印成多行
    按之字形顺序打印二叉树
    对称的二叉树
    二叉树的下一个结点
    删除链表中重复的结点
    链表中环的入口结点
    字符流中第一个不重复的字符
    基数排序的理解和实现(Java)
  • 原文地址:https://www.cnblogs.com/mazhitao/p/7454875.html
Copyright © 2020-2023  润新知