zoukankan      html  css  js  c++  java
  • AOP理解

    https://blog.csdn.net/qq_26525215/article/details/52400791

    使用场景:

      日志、鉴权等一些和业务无关且重复的功能

    几个基本概念:

      切点:需要增加功能的位置(可以通过注解或者pointCut方法)

      切面:需要增加的功能的代码(通过定义一个xxAcept类,选择性的添加方法,为切点在不同位置【代码段的前中后】增加功能)

      织入:Spring和其它纯Java AOP框架一样,在运行时完成织入

      通知:通知有各种类型,其中包括“around”、“before”和“after”等通知

    动态代理实现AOP(JDKProxy):

       通过动态代理的方式实现AOP,动态代理生成的这个对象,在具体的方法上,新增了切面中定义的功能,使得我们在不改变原对象的基础上新增了我们需要的功能。

       代理会生成一个类,这个类继承这个接口,并且代理要切面的类,在实现具体的方法时,实际上是调用了原来类的方法,只是在调用前和调用后做了一些事情而已。 

      这种方式只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,可以通过CGLib创建动态代理。

      

    AOP失效的情景,为什么会失效?

    https://blog.csdn.net/u012373815/article/details/77345655

    1.在对象内部的方法中调用该对象的其他使用aop机制的方法,被调用方法的aop注解失效。

    原因:

      正常aop的顺序是这样的:一个类作为被代理对象,动态的生成一个代理对象,在这个新的代理对象中的invoke()方法里会执行一些额外新增的功能和被代理对象的某个方法,而这个方法是通过调用被代理对象的这个方法而实现的。当使用注解增加一个aop切点时,实际上是把这个类作为了一个被代理对象,因此在执行一个被调用的方法时,这个aop会失效。

    2.private方法不生效

       private方法一定是这个类的某个方法去调用的,本质和上一种情况是一样的,因此aop失效。

    初识aop的一个demo:

    MyAspect.java

    package com.test.aoptest.aspect;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import java.util.Arrays;
    
    /**
     * @author gaoyuan 
     * @date 2019/7/15 11:27
     */
    @Aspect
    @Component
    public class MyAspect {
    
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        @Pointcut("execution(public * com.test.aoptest.service.*.*(..))")
        public void pointCut(){
    
        }
    
        @Before("pointCut()")
        public void before(JoinPoint joinPoint) throws Throwable {
            // 接收到请求,记录请求内容
            logger.info("【注解:Before】------------------切面  before");
            ServletRequestAttributes attributes = (ServletRequestAttributes)
                    RequestContextHolder.getRequestAttributes();
            // 记录下请求内容
            logger.info("【注解:Before】执行的业务方法名=CLASS_METHOD : " +
                    joinPoint.getSignature().getDeclaringTypeName() + "." +
                    joinPoint.getSignature().getName());
            logger.info("【注解:Before】业务方法获得的参数=ARGS : " + Arrays.toString(joinPoint.getArgs()));
        }
    
        @AfterReturning(returning = "ret", pointcut = "pointCut()")
        public void afterReturning(Object ret) throws Throwable {
            // 处理完请求,返回内容
            logger.info("【注解:AfterReturning】这个会在切面最后的最后打印,方法的返回值 : " + ret);
        }
    
        @AfterThrowing("pointCut()")
        public void afterThrowing(JoinPoint jp){
            logger.info("【注解:AfterThrowing】方法异常时执行.....");
        }
    
        @After("pointCut()")
        public void after(JoinPoint jp){
            logger.info("【注解:After】方法最后执行.....");
        }
    
        @Around("pointCut()")
        public Object around(ProceedingJoinPoint pjp) {
            logger.info("【注解:Around . 环绕前】方法环绕start.....");
            try {
                //如果不执行这句,会不执行切面的Before方法及controller的业务方法
                Object o =  pjp.proceed();
                logger.info("【注解:Around. 环绕后】方法环绕proceed,结果是 :" + o);
                return o;
            } catch (Throwable e) {
                e.printStackTrace();
                return null;
            }
        }
    }

    AopConfiguration.java

    package com.test.aoptest.configuration;
    
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    /**
     * @author gaoyuan 
     * @date 2019/7/15 11:39
     */
    @Configuration
    @ComponentScan("com.test.aoptest.aspect")
    @EnableAspectJAutoProxy
    public class AopConfiguration {
    }

    HelloController.java

    package com.test.aoptest.controller;
    
    import com.test.aoptest.service.HelloService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author gaoyuan (yuangao@rd.netease.com)
     * @date 2019/7/15 11:43
     */
    @RestController
    @RequestMapping("/")
    public class HelloController {
    
        @Autowired
        private HelloService helloService;
    
        @RequestMapping("hello")
        public String hello() {
            return helloService.sayHello();
        }
    
    }

    HelloService.java

    package com.test.aoptest.service;
    
    /**
     * @author gaoyuan
     * @date 2019/7/15 11:23
     */
    public interface HelloService {
        String sayHello();
    
        void printHello();
    
        int addUser(String name, String pass);
    
    }

    HelloServiceImpl.java

    package com.test.aoptest.service.impl;
    
    import com.test.aoptest.service.HelloService;
    import org.springframework.stereotype.Service;
    
    /**
     * @author gaoyuan 
     * @date 2019/7/15 11:23
     */
    @Service
    public class HelloServiceImpl implements HelloService {
        @Override
        public String sayHello() {
            return "hello";
        }
    
        @Override
        public void printHello() {
            System.out.println("hello");
        }
    
        @Override
        public int addUser(String name , String pass)
        {
            System.out.println("执行Hello组件的addUser添加用户:" + name);
            if(name.length() < 3 || name.length() > 10)
            {
                throw new IllegalArgumentException("name参数的长度必须大于3,小于10!");
            }
            return 20;
        }
    }

    AoptestApplication.java

    package com.test.aoptest;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    @SpringBootApplication
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @EnableConfigurationProperties
    public class AoptestApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(AoptestApplication.class, args);
        }
    
    }

    application.properties

    server.port=8080
    spring.profiles.active=dev

    application-dev.properties

    这个文件其实撒都没有,做作了一下 啊哈哈哈

  • 相关阅读:
    单细胞分析实录(13): inferCNV结合UPhyloplot2分析肿瘤进化
    单细胞分析实录(12): 如何推断肿瘤细胞
    单细胞分析实录(11): inferCNV的基本用法
    用网络图展示富集分析
    R绘图(6): 拯救初学者——发表级绘图全能包ggpubr
    R绘图(5): 一文学会桑基图的画法
    db2备份与还原
    SAP R/3系统的启动和关闭
    重启sap过程
    DB2重启数据库实例
  • 原文地址:https://www.cnblogs.com/gaoquanquan/p/11202804.html
Copyright © 2011-2022 走看看