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
- 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.
- 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.
- 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:
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.
A análise do aplicativo do objeto proxy dinâmico JDK no projeto, conforme mostrado na figura:
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:
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.