美文网首页
Spring Boot学习笔记三:AOP的实现原理

Spring Boot学习笔记三:AOP的实现原理

作者: 哪吒小子 | 来源:发表于2018-12-05 17:01 被阅读4次

    引言

    Advice,通知增强,主要包括五个注解Before,After,AfterReturning,AfterThrowing,Around

    @Before 在切点方法之前执行

    @After 在切点方法之后执行

    @AfterReturning 切点方法返回后执行

    @AfterThrowing 切点方法抛异常执行

    @Around 属于环绕增强,能控制切点执行前,执行后,,用这个注解后,程序抛异常,会影响@AfterThrowing这个注解

    环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值

    代码实现

    1.引入POM

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    

    2.AOP拦截类

    package com.nezha.learn.demo.aop;
    
    import com.nezha.learn.demo.User;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class HelloAspect {
    
        @Pointcut("execution(* com.nezha.learn.demo.api.Hello.login(..))")
        private void pointCutLogin(){ }
    
    
        @Before(value = "pointCutLogin()")
        public void before(JoinPoint joinPoint){
            Object[] args = joinPoint.getArgs();
            String className = joinPoint.getSignature().getDeclaringTypeName();
            String methodName = joinPoint.getSignature().getName();
            System.out.println("before开始执行--->>>"+className+"/"+methodName+",参数是:"+String.valueOf(args[0]));
        }
    
        @After(value = "pointCutLogin()")
        public void after(JoinPoint joinPoint){
            Object[] args = joinPoint.getArgs();
            String className = joinPoint.getSignature().getDeclaringTypeName();
            String methodName = joinPoint.getSignature().getName();
            System.out.println("after开始执行--->>>"+className+"/"+methodName+",参数是:"+String.valueOf(args[0]));
        }
    
        @Around(value = "pointCutLogin()")
        public Object around(ProceedingJoinPoint proceedingJoinPoint){
            Object[] args = proceedingJoinPoint.getArgs();
            String className = proceedingJoinPoint.getSignature().getDeclaringTypeName();
            String methodName = proceedingJoinPoint.getSignature().getName();
            System.out.println("Around开始执行--->>>"+className+"/"+methodName+",参数是:"+String.valueOf(args[0]));
            Object[] input = {"nezha"};
            Object proceed = null;
            try {
                //这里是执行方法的
                proceed = proceedingJoinPoint.proceed(input);
            }catch (Throwable t){
                t.printStackTrace();
            }
            System.out.println("===获得的proceed结果是:"+(User)proceed);
            //!!!这边如果不把proceed返回出去,拦截的方法也不会进行结果返回的!
            return proceed;
        }
    }
    

    3.被拦截的方法

    package com.nezha.learn.demo.api;
    
    import com.nezha.learn.demo.User;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/Hello")
    public class Hello {
    
        @RequestMapping("/user/{name}")
        public User login(@PathVariable("name") String name){
            User user = new User(name,26);
            return user;
        }
    }
    

    4.User类

    package com.nezha.learn.demo;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private String name;
        private Integer age;
        public User(){
    
        }
        public User(String username, Integer age) {
            this.name = username;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User String is:"+name+",age:"+age;
        }
    }
    

    参考文献

    1. Spring AOP的实现原理:http://www.importnew.com/24305.html
    2. 从源码入手,带你一文读懂Spring AOP面向切面编程:https://zackku.com/spring-aop/

    相关文章

      网友评论

          本文标题:Spring Boot学习笔记三:AOP的实现原理

          本文链接:https://www.haomeiwen.com/subject/kqywcqtx.html