1. Introdução
Durante o processo de desenvolvimento, geralmente precisamos escrever muitos exemplos:
@GetMapping ("/id/get") resultado público getById (string id) lança a exceção {log.info ("o parâmetro de solicitação é:"+id); verifique (novo verifyparam ("ID do departamento", id)); Resultado resultado = novo resultado ("obtido com êxito através do ID!", Service.QuerybyId (ID)); log.info ("A mensagem de retorno é:"+resultado.toString ()); resultado de retorno; }Parâmetros de solicitação de impressão e parâmetros de retorno, e essas operações existem em cada método, tornando nosso código mais redundante. Por esse motivo, podemos usar proxy dinâmico para usar parâmetros de impressão e imprimir mensagens de retorno como seções e usar expressões de corte de ponto para cortá-las em cada método.
2. Etapas
1. Introduzir dependências relacionadas à AOP:
<!-Dependências relacionadas à AOP-> <Depency> <Puerpid> org.springframework.boot </foupiD> <TRAFACTID> Spring-Boot-Starter-AOP </ArtifactId> </Dependence>
Após a introdução de dependências, a Spring-AOP carregará as dependências necessárias. A primavera usa as aspectos por padrão para implementar notificações.
Entre eles, o aspectojweaver.jar contém arquivos que analisam as expressões de corte de aspecto. Essa dependência também é necessária ao usar expressões pontuais para lidar com transações.
2. Configuração:
1) Crie uma classe de configuração:
/*** @function Descrição: classe AOP usada para operações da camada do controlador* @Author Administrator*/ @componente // manipulam objetos para mudar para gerenciamento @aspect // representam esta classe como uma classe de aspecto controlador {}A anotação @Aspect representa que é uma classe de gerenciamento de aspectos, onde as expressões de corte de pontos podem ser definidas e a estrutura de aspecto o analisará.
2) Defina a expressão pontual:
@PointCut ("Execution (public*com.hzt.Manage.*. Web.Controller ..*.Onde @pointcut representa esse método como uma expressão de corte de ponto. Seu valor é uma expressão pontual, onde o valor pode ser omitido e seu formato aproximado é:
@Annotation (tag de expressão + formato de expressão)
Para o formato, os indicadores de ponto de ponta dos aspectos suportados pela Spring AOP são os seguintes:
1. Execução: o ponto de conexão usado para corresponder à execução do método;
2. Dentro: usado para corresponder à execução de métodos dentro do tipo especificado;
3. Isto: Método de execução usado para corresponder ao tipo de objeto de proxy AOP atual; Observe que a correspondência de tipo do objeto AOP Proxy, que pode incluir a introdução de interfaces e a correspondência do tipo;
4. Alvo: método de execução usado para corresponder ao tipo de objeto de destino atual; Observe que a correspondência de tipo do objeto de destino é o tipo de correspondência, para que a introdução da interface não esteja incluída;
5. ARGS: O método de execução é usado para corresponder aos parâmetros passados pelo método atualmente executado como o tipo especificado;
6. @within: usado para corresponder aos métodos de retenção no tipo de anotação especificada;
7. @target: método de execução usado para corresponder ao tipo de objeto de destino atual, onde o objeto de destino contém a anotação especificada;
8. @args: usado para corresponder à execução dos parâmetros passados no método atualmente executado que mantém a anotação especificada;
9. @annotation: Usado para corresponder ao método que atualmente executa o método mantém a anotação especificada;
10. Bean: primavera de extensão AOP, as aspectos não possuem um método de execução para combinar objetos de feijão com um nome específico;
11. Pointcut de referência: significa referir -se a outros pontos de entrada de nomeação, apenas o estilo @apectj suporta, mas não no estilo de esquema.
O ARGS define os parâmetros ao executar o método de expressão pontual:
@PointCut (value = "Execution (public*com.hzt.Manage.
Nós nos concentramos na expressão do ponto de conexão do método de execução, e sua estrutura aproximada é:
execução (modificadores-padrão?
1. MACHING MODIFICADOR (Patadrão Modificador?) (Pode ser omitido)
2. A correspondência do valor de retorno (padrão do tipo ret) pode representar qualquer valor de retorno para *, como (String) representa apenas filtrar o ponto de entrada que retorna o tipo de string, nomes de classe do caminho completo, etc. (não pode ser omitido)
3. Declaração do tipo padrão? Por exemplo, *. Manage representa o pacote de primeiro nível como arbitrário e o pacote de segundo nível como o nome do gerenciamento. *.. Gerenciar representa os pacotes de subclasse em todos os pacotes Gerenciar. com .. *. Comtroller representa todos os pacotes de controladores em pacotes de com, etc., e * significa que todos os pacotes correspondem. (Não omitido)
4. O nome do método corresponde (padrão de nome) pode especificar o nome do método ou * representar tudo, obter * representa todos os métodos que começam com get, ou você pode especificar o prefixo * Get Representa qualquer método com sufixo arbitrário de get (não omitido)
5. A correspondência de parâmetros ((param-padrão)) pode especificar um tipo de parâmetro específico, vários parâmetros são separados por "," e cada parâmetro também pode ser "*" para corresponder aos parâmetros de qualquer tipo, como (string) significa um método para corresponder a um parâmetro de sequência; (*, String) significa um método para corresponder a dois parâmetros, o primeiro parâmetro pode ser de qualquer tipo e o segundo parâmetro é de um tipo de string; (..) pode ser usado para representar qualquer parâmetro (não omitido)
6. Combinação do tipo de exceção (padrão de arremesso?)
3. Defina o método da faceta
@Around ("privilége ()") objeto público em torno (prosseguirjOinpoint pjd) lança arremesso {// obtenha o nome do método string className = pjd.getSignature (). GetClass (). GetName (); // Obtenha o método de execução Nome String MethodName = pjd.getSignature (). GetName (); / ** Log de inicialização Impressão*/ logger log = loggerFactory.getLogger (ClassName); // Defina o resultado do objeto de parâmetro de retorno = null; // Registre o tempo de início long start = system.currenttimemillis (); // obtenha objeto de parâmetros do método [] args = pjd.getargs (); String params = "Os parâmetros de solicitação front-end são:"; // Obtenha a solicitação de coleta de parâmetros e travessia e emenda para (objeto objeto: args) {params + = object.toString () + ","; } params = params.substring (0, params.length () - 1); // Imprima o parâmetro da solicitação log.info (className + "Class" + MethodName + "" + Params); // execute o resultado do método de destino = pjd.proeced (); // Imprima o log.info de mensagem de retorno ("O método retorna a mensagem como:" + (resultado de resultado de resultados? (Resultado) Resultado: Resultado)); // Obtenha o tempo de execução Log.info (MethodName + "O tempo de execução do método é:" + (System.currenttimEmillis () - start)); resultado de retorno; }5. Notificação surround @Around, como mostrado no código acima, é notificação surround, que possui o parâmetro ProceedingJoinPoint
Onde o pjd.proeced (); O método representa a execução do método de destino e a obtenção de um valor de retorno do tipo de objeto. Podemos processar o valor de retorno, como processamento de decoração, etc.
O valor do retorno é o resultado da execução do método. No código acima, primeiro obtém o nome da classe, o nome do método, os parâmetros de solicitação do método etc., executa a impressão em splicing e registra o tempo de início da execução do método e o imprime no log.
Em seguida, execute o método, obtenha o resultado do retorno do método, imprima o tempo de execução e o resultado da execução.
Finalmente, o resultado da execução é retornado. Ou seja, a codificação da seção AOP da mensagem de solicitação e a mensagem de retorno é concluída.
Onde o @around o representa como um método de notificação circundante, ele possui os seguintes tipos:
1. @Ebe antes da notificação, que possui o parâmetro de junção de parâmetro de solicitação, que é usado para conectar os detalhes da conexão do ponto de conexão atual, geralmente incluindo o nome do método e o valor do parâmetro. O corpo do método é executado antes da execução do método e os parâmetros do método não podem ser alterados, nem os resultados da execução do método não podem ser alterados.
@Before (Value = "PrivileGe ()") public void antes (JUNCIPIGN JUNJOint) {}2. Notificação de postagem @after: notificação de que a execução é realizada, independentemente de ocorrer uma exceção após a execução do método de destino. Na pós-notificação, o resultado da execução do método de destino não pode ser acessado (porque pode ocorrer uma exceção) e o resultado da execução do método não pode ser alterado.
@Before (value = "privilEGE ()") public void depois (juntpoint Jun JoinPoint) {}3. @Afterreturning retorna uma notificação. A notificação que é executada apenas quando o método de destino é executado é o mesmo que o método pós-organizado. Ele pode acessar o resultado da execução do método (devido à execução normal) e aos detalhes da conexão do método, mas não pode alterar o resultado da execução do método.
@AfterReturning (Value = "Privilege ()") public void após revolver (JunnPoint Junção, resultado do objeto) {}O valor de retorno armazenado no resultado é o método.
4. Notificação de exceção do @afterwring: código que será executado somente quando ocorrer uma exceção no método de destino. O atributo de arremesso representa uma exceção lançada durante a execução do corpo do método, e seu valor deve ser consistente com o valor da exceção no método.
@AfterWrowing (Value = "Privilege ()", Throwing = "Ex") Public void Exceed (JONCOPOint Junção, Exceção ex) {}3. Teste
Escreva um método de controlador
@RestController@requestmapp ("/api/v1/dept") public Class DeptController estende Basecontroller {/** classe de log*/logger privado Log = LoggerFactory.getLogger (getClass ()); / ** meu próprio serviço*/ @AUTOWIRED PRIVIDO PRIVIDO DE DEPTROSTIVE; /*** @function Descrição: Método para conteúdo do departamento de consulta com base no ID* @return Dept*/@getMapping ("/id/get") resultado público getById (string id) lança exceção {verifique (new verifyparam ("departamento id", id)); Retornar novo resultado ("obtido com sucesso através do ID!", Service.QueryById (ID)); }}Dessa maneira, o método em nossa camada de controlador é muito conciso.
Resultados do teste:
2018-04-10 22: 59: 27.468 INFO 1460 --- [NIO-8088-EXEC-5] nProedingJoinPoint $ MethodSignatureImpl: O parâmetro de solicitação front-end do getByID é: 22
2018-04-10 22:59:27.470 INFO 1460 --- [nio-8088-exec-5] nProceedingJoinPoint$MethodSignatureImpl: The method returns the message as:Result [result_code=suc, result_message=Successfully obtained department information through id!, data=Dept [id=22, no=22, name=22, manager=22, description=22, phone=22, CreateTime = qui 19 de abril 23:38:37 CST 2018, Edittime = null]]
2018-04-10 22: 59: 27.470 INFO 1460 --- [NIO-8088-EXEC-5] nProedingJoinPoint $ MethodSignatureImpl: O tempo de execução do método getById é: 2
Isso permite imprimir parâmetros de solicitação, resultados de retorno, tempo de execução etc. com impressão elegante, concisa e concisa!