• AOP 实现自定义注解


    1.自定义注解
    2.编写 AOP
    3.测试

    1.自定义注解

    package com.base.yun.spring.aop;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /** 
    * 说明: 
    * 定义日志注解 
    */  
    @Target(ElementType.METHOD)  
    @Retention(RetentionPolicy.RUNTIME)  
    @Documented  
    public @interface FileLog {  
        
      String value() default "记录日志";  
        
    }  


    2.编写 AOP

    package com.base.yun.spring.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.springframework.stereotype.Component;
    
    /**
     * 说明: 日志的切面处理程序
     */
    @Aspect
    @Component
    public class LogAspect {
    
        @Before("within(com.base.yun.spring.service.*) && @annotation(fileLog)")
        public void doAccessCheck(JoinPoint jp, FileLog fileLog) {
            System.out.println("前置通知-->>");
        }
    
        @After("within(com.base.yun.spring.service.*) && @annotation(fileLog)")
        public void doAfterReturning(JoinPoint jp, FileLog fileLog) {
            System.out.println("后置通知-->>");
        }
    
        @Around("within(com.base.yun.spring.service.*) && @annotation(fileLog)")
        public Object doAround(ProceedingJoinPoint pJoinPoint, FileLog fileLog) throws Throwable {
            System.out.println("环绕通知开始");
            // 这里如果pJoinPoint.proceed()不执行,后面拦截到的方法都不会执行,非常适用于权限管理
            Object result = pJoinPoint.proceed();
            System.out.println("环绕通知结束");
            return result;
        }
    
        @AfterReturning("within(com.base.yun.spring.service.*) && @annotation(fileLog)")
        public void addSuccessLog(JoinPoint jp, FileLog fileLog) {
            Object[] parames = jp.getArgs();
            // 获取目标方法体参数
            String className = jp.getTarget().getClass().toString();
            // 获取目标类名
            String signature = jp.getSignature().toString();
            // 获取目标方法签名
            String methodName = signature.substring(signature.lastIndexOf(".") + 1,
                    signature.indexOf("("));
            // 获取注解值
            String desc = fileLog.value();
            // 把调用的信息写到日常记录信息里面去...
            System.out.println("最终通知注解值:"+desc);
        }
    
        // 标注该方法体为异常通知,当目标方法出现异常时,执行该方法体
        @AfterThrowing(pointcut = "within(com.base.yun.spring.service.*) && @annotation(fileLog)", throwing = "e")
        public void addExceptionLog(JoinPoint jp, FileLog fileLog, Exception e) {
            System.out.println("异常通知-->");
            // 把错误信息写到错误日志文件里面去...
        }
    }


    3.测试

    <aop:aspectj-autoproxy/>  
         <bean class="com.base.yun.spring.aop.LogAspect"/> 
         <bean id="purchaseService" class="com.base.yun.spring.service.PurchaseService" />
    package spring;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.base.yun.spring.service.PurchaseService;
    
    public class AopTest {
    
        @Test
        public void testAop() {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("user.xml");
            PurchaseService service = ctx.getBean("purchaseService",PurchaseService.class);
            service.purchaseProduct("电风扇", 98, "日用品"); 
        }
        
    }

    测试结果:

    环绕通知开始
    前置通知-->>
    购买商品。。。
    环绕通知结束
    后置通知-->>
    最终通知注解值:记录日志
  • 相关阅读:
    singleton 创建static类型的对象
    记忆曲线 遗忘曲线
    创建classic 得到函数 调用函数
    abstract factory 创建相互关联的类
    log4j PatternLayout
    C#中override重写与new隐藏的区别,以及C#与Java的override区别 转
    iptables如何做内网的https端口映射 转
    得到一棵树 取自表内自递归(即ID 与ParentID)
    Common.TcpLibTcpClientT
    得到汉字的首拼音字符 ZT
  • 原文地址:https://www.cnblogs.com/yun965861480/p/7650340.html
Copyright © 2020-2023  润新知