Código principal AOP + notas de uso

1. Introdução de substantivo

1. Ponto de conexão (JoinPoint)

Um ponto de conexão é um ponto que pode ser inserido em um aspecto durante a execução do aplicativo. Esses pontos podem ser quando um método é chamado ou mesmo quando um campo é modificado. É um conceito virtual.Por exemplo, ao pegar o metrô, você pode descer em todas as estações, portanto, cada estação é um ponto de acesso. Se houver vários métodos em um objeto, cada método será um ponto de conexão.

2. Pointcut

O ponto de entrada é o ponto de conexão de alguns enviados especiais e é o local onde avisos específicos são anexados. Por exemplo, quando você pega o metrô e desce em uma determinada estação, esta estação é o ponto de entrada

  1. O ponto de conexão é um conceito virtual, que pode ser entendido como todas as oportunidades que atendem às condições de digitalização do ponto de corte.
  2. Um exemplo específico: Por exemplo, ao dirigir por uma rodovia, existem muitas saídas (pontos de conexão) nesta rodovia, mas não sairemos em todas as saídas, mas apenas escolheremos a saída (ponto de corte) que precisamos seguir para fora.
  3. Simplesmente entenda que cada saída é um ponto de conexão, mas a saída que usamos é o ponto de contato. Cada aplicativo possui vários locais adequados para tecer notificações e esses locais são pontos de conexão. Mas apenas o local específico que escolhemos é o ponto de contato.

3. Aspecto

O aspecto é a combinação do aviso e do ponto de entrada. O aviso estipula quando e o que fazer, e o ponto de entrada estipula onde. Por exemplo, "desça na estação oeste às 8 horas" é um corte transversal. Então, às 8 horas, a ação para desligar é uma notificação. A West Station é um ponto de entrada.

4. Introdução

Permite-nos adicionar novos atributos de método às classes existentes.

5. Tecelagem

O processo de aplicação de aspectos a objetos de destino e criação de objetos proxy. O ponto tangente é tecido no objeto alvo no ponto de conexão especificado (ponto tangente). No ciclo de vida de um alvo, existem vários pontos que podem ser integrados em:

Período de compilação, período de carregamento de classe, tempo de execução

6. Conselhos

A notificação define quando e o que fazer. Os tipos de notificações são os seguintes:

Insira a descrição da imagem aqui

São eles: notificação de postagem, notificação de retorno, notificação de exceção, notificação surround e notificação frontal


2. Coordenadas e código do modelo

Adicionar dependência AOP

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

A seguir está o código do modelo

@Slf4j
@Aspect
@Component
public class SysLogAspect {
    
    
    /**
     * @Pointcut注解用于定义切入点
     * bean("spring容器中bean的名字")这个表达式为切入点表达式定义的一种语法,
     * 它描述的是某个bean或多个bean中所有方法的集合为切入点,这个形式的切入点
     * 表达式的缺陷是不能精确到具体方法的.
     */
    @Pointcut("bean(sysUserServiceImpl)")
    public void doLog(){
    
    }//此方法只负责承载切入点的定义

    /**
     * @Around注解描述的方法,可以在切入点执行之前和之后进行业务拓展,
     * 在当前业务中,此方法为日志通知方法
     * @param joinPoint 连接点对象,此对象封装了要执行的切入点方法信息.
     * 可以通过连接点对象调用目标方法,这里的ProceedingJoinPoint类型只能应用于@Around描述的方法参数中
     * @return 目标方法的执行结果
     * @throws Throwable
     */
    @Around("doLog()")
    public Object doAround(ProceedingJoinPoint jp)throws Throwable{
    
    
        log.info("Start:{}",System.currentTimeMillis());
        try {
    
    
            Object result = jp.proceed();//执行目标方法(切点方法中的某个方法)
            log.info("After:{}",System.currentTimeMillis());
            return result;//目标业务方法的执行结果
        }catch(Throwable e){
    
    
            e.printStackTrace();
            log.error("Exception:{}",System.currentTimeMillis());
            throw e;
        }
    }
}

3. Análise de fundo

Análise do princípio de funcionamento dos aspectos da mola

Quando o método de negócio de destino correspondente ao ponto de entrada dentro de nosso aspecto é executado, a camada inferior acessará o método de notificação no aspecto por meio do objeto proxy e, em seguida, usará o método de notificação para aprimorar o negócio de destino.

Insira a descrição da imagem aqui

A análise do aplicativo do objeto proxy dinâmico JDK no projeto, conforme mostrado na figura:

Insira a descrição da imagem aqui

Entre eles: o proxy AOP padrão do projeto springboot é o proxy CGLIB. Se você deseja ser um proxy JDK, é necessário configurar o seguinte no arquivo de configuração springboot:

spring: 
  aop: 
    proxy-target-class: false

Análise de aplicativo de objeto proxy dinâmico CGLIB no projeto, conforme mostrado na figura:

Insira a descrição da imagem aqui

4. Aplicação avançada da tecnologia AOP na primavera

Tipo de notificação AOP

O módulo Spring Framework AOP define os tipos de notificação, que são os seguintes:

  • @Around (A notificação com a prioridade mais alta entre todas as notificações pode ser expandida de forma flexível antes e depois da execução do método de destino.)
  • @Before (Chamado antes de o método de destino ser executado)
  • @AfterReturning (executado quando o método de destino termina normalmente)
  • @AfterThrowing (executado quando o método de destino termina de forma anormal)
  • @After (execute quando o método de destino terminar, ele será executado quando o método de destino terminar normalmente e de forma anormal)

Com base na compreensão dos tipos de notificação, analise o tempo de execução específico da notificação por meio da análise de caso e analise o código-chave

package com.chen.service.aspect;
@Aspect
@Component
public class SysTimeAspect {
    
    
    @Pointcut("bean(sysRoleServiceImpl)")
    public void doTime(){
    
    }

    @Before("doTime()")
    public void doBefore(JoinPoint jp){
    
    
        System.out.println("@Before");
    }

    @After("doTime()")
    public void doAfter(){
    
    
        System.out.println("@After");
    }

    @AfterReturning("doTime()")
    public void doAfterReturning(){
    
    
        System.out.println("@AfterReturning");
    }

    @AfterThrowing("doTime()")
    public void doAfterThrowing(){
    
    
        System.out.println("@AfterThrowing");
    }
    //最重要,优先级也是最高
    @Around("doTime()")
    public Object doAround(ProceedingJoinPoint joinPoint)throws Throwable{
    
    
        try {
    
    
            System.out.println("@Around.before");
            Object result = joinPoint.proceed();
            System.out.println("@Around.AfterReturning");
            return result;
        }catch(Exception e){
    
    
            System.out.println("@Around.AfterThrowing");
            e.printStackTrace();
            throw e;
        }finally {
    
    
            System.out.println("@Around.after");
        }
    }

}

Entre eles, não é necessário definir todos os métodos de notificação em projetos reais, e métodos de notificação serão adicionados em combinação com negócios específicos.

Expressão de ponto de entrada AOP

No projeto Spring, a expressão pointcut pode ser dividida em dois tipos:

  • Definição de expressão de ponto de entrada de granulação grossa (não precisa para o método específico), como feijão, dentro da expressão
  • Definição de expressão de ponto de entrada refinada (pode ser precisa para o método específico), como execução, expressão @annotation

Expressão de pointcut de granulação grossa

  • análise de caso de expressão de bean ("nome do bean")
1) bean(sysUserServiceImpl),sysUserServiceImpl类中所有方法集合为切入点
2) bean(*ServiceImpl),以ServiceImpl结尾的所有方法集合为切入点
  • dentro de ("nome do pacote. tipo") expressão análise de caso
1) within(com.pj.service.SysUserServiceImpl),SysUserServiceImpl类中所有方法集合为切入点
2) within(com.pj.service.*),com.pj.service包下所有类中的方法集合为切入点
3) within(com.pj.service..*),com.pj.service包以及子包中所有类中方法的集合为切入点

Expressão de pointcut refinada

  • execução ("Nome completo da classe de valor de retorno. Nome do método (lista de parâmetros)") expressão análise de caso
1) execution(int com.cy.pj.service.SysUserService.validById(Integer,Integer))
2) execution(* com.cy.pj.service..*.*(..))
  • análise de caso de expressão @annotation ("nome completo da classe anotada")
1) @annotation(com.annotation.RequiredCache),由RequiredCache注解描述的方法为缓存切入点方法
2) @annotation(com.annotation.RequiredLog),由RequiredLog注解描述的方法为日志切入点方法

Análise de definição de prioridade de aspecto AOP

Quando há vários aspectos no projeto, e correspondendo ao mesmo ponto de entrada, se a execução do método de notificação no aspecto requer requisitos de ordem estritos, precisamos definir a prioridade do aspecto neste momento. Esta prioridade pode ser descrita pela anotação @Order (prioridade numérica), quanto menor o número, maior a prioridade. Por exemplo:

Defina a prioridade do aspecto do log, o código-chave é o seguinte:

@Order(2)
@Aspect
@Component
public class SysLogAspect{
    
    }

Para definir a prioridade do aspecto em cache, o código-chave é o seguinte:

@Order(1)
@Aspect
@Component
public class SysCacheAspect{
    
    }

Se nenhuma prioridade for especificada por padrão, o padrão é a prioridade mais baixa. Múltiplas fatias sob o mesmo corte de ponto formarão uma cadeia de fatias.

Acho que você gosta

Origin blog.csdn.net/weixin_40597409/article/details/113448864
Recomendado
Clasificación