O que é AOP
AOP (programação orientada a aspectos, programação orientada a aspectos) pode ser considerada um suplemento e melhoria da OOP (programação orientada a objetos). A OOP introduz conceitos como encapsulamento, herança e polimorfismo para estabelecer uma hierarquia de objetos para simular uma coleção de comportamentos públicos. Quando precisamos introduzir o comportamento público em objetos dispersos, o OOP parece impotente. Ou seja, o OOP permite definir relacionamentos de cima para baixo, mas não é adequado para definir relacionamentos da esquerda para a direita. Por exemplo, a função de log. O código de log geralmente é disperso horizontalmente em todos os níveis de objeto, sem qualquer relação com a funcionalidade principal do objeto ao qual ele está disperso. O mesmo vale para outros tipos de código, como segurança, manipulação de exceções e transparência. Esse tipo de código irrelevante espalhado em todos os lugares é chamado de código cruzado. No design do OOP, causa muita duplicação de código, que não é propícia à reutilização de cada módulo.
Introdução
O padrão de design Java que escrevi há algum tempo - o padrão de proxy. Recentemente, quando eu estava olhando para a Spring AOP, senti que deveria haver conexões estreitas no padrão de proxy, então decidi entender o princípio da implementação da Spring AOP.
Falando em AOP, temos que falar sobre OOP. Os conceitos de encapsulamento, herança e polimorfismo são introduzidos na OOP para estabelecer uma hierarquia de objetos para simular uma coleção de comportamentos públicos. No entanto, se precisarmos introduzir peças comuns para alguns objetos, o OOP introduzirá muitos código duplicados. Por exemplo: Função de log.
A tecnologia AOP usa uma técnica chamada "corte cruzado" para dissecar o interior do objeto encapsulado e encapsular os comportamentos comuns que afetam várias classes em um módulo reutilizável, o que pode reduzir a duplicação de código do sistema, reduzir o acoplamento entre os módulos e facilitar a operabilidade e manutenção futura. AOP divide o sistema de software em duas partes: preocupação central e atenção cruzada. O principal processo de processamento de negócios é o foco principal, e a parte que pouco tem a ver com isso é o foco transversal. Uma característica das preocupações cruzadas é que elas geralmente ocorrem em múltiplas preocupações principais e são basicamente semelhantes em todos os lugares. Por exemplo, autenticação de permissão, log e processamento de transações.
Princípio da implementação
Quando eu estava aprendendo o modo proxy, aprendi que o modo proxy é dividido em proxy dinâmico e proxy estático. Agora, primeiro implementaremos nossa própria estrutura AOP baseada no modelo de proxy e depois estudaremos os princípios de implementação da AOP da Spring.
Primeiro, é implementado com um proxy estático. A chave do proxy estático é implementar uma interface comum entre o objeto proxy e o objeto de destino, e o objeto proxy mantém uma referência ao objeto de destino.
Código de interface pública:
interface pública IHELLO {/*** Método de negócios*@param str*/void SayHello (String str);} Código da classe de destino: classe pública Hello implementa Ihello {@OverridePublic void Sayhello (String str) {System.out.println ("hello"+str);}} Para o código da classe Proxy, adicionamos a função de log a ele e executamos métodos específicos antes e após o início do método. Não é particularmente semelhante ao AOP?
classe pública proxyhello implementa ihello {private ihello hello; public proxyhello (ihello hello) {super (); this.hello = hello;}@substituir o void de substituto SayHello (String str) {Logger.start (); // Adicione método específico Hello.sayhello (str); Logger.end ();}} Código da classe de log:
public class Logger {public static void start () {System.out.println (new Date ()+ "diga olá inicial ...");} public static void end () {System.out.println (new Date ()+ "Say Hello end");}} Código de teste:
Public classe Test {public static void main (string [] args) {ihello hello = new proxyhello (new hello ()); // se precisarmos da função de registro, use a classe proxy // ihello hello = new hello (); // se não precisarmos da função de log de log, use a classe de destino hello.sayhello ("amanhã"; }}Dessa forma, implementamos a AOP mais simples, mas haverá um problema: se tivermos muitas aulas como Hello, devemos escrever muitas classes como o HelloProxy? De fato, também é uma coisa muito problemática. Após o JDK1.3, o JDK nos fornece uma classe API java.lang.reflect.invocationHandler. Esta classe nos permite fazer algo dinamicamente por alguns métodos quando a JVM chama os métodos de uma determinada classe. Vamos implementar a implementação de proxy dinâmico.
A implementação dinâmica de proxy implementa principalmente a InvocationHandler e injeta o objeto de destino no objeto proxy, usando o mecanismo de reflexão para executar o método do objeto de destino.
A implementação da interface é a mesma que o proxy estático, o código da classe Proxy:
public class dynaproxyhello implementa a InvocationHandler {destino de objeto privado; // Objeto de destino/*** instantam o objeto de destino através da reflexão* @param objeto* @return*/public Object bind (object) {thisget.getClass (). Este);}@substituir o objeto de publicação (proxy do objeto, método do método, objeto [] args) lança arrastável {resultado de objeto = null; logger.start (); // Adicione métodos adicionais // métodos para executar objetos de destino através do mecanismo de reflexão resultado = método.inVoke (this.Target, args); logger.END (); Código da classe de teste:
public class dynatest {public static void main (string [] args) {ihello hello = (ihello) new dynaProxyhello (). bind (new hello ()); // se precisarmos de log da função de log, use a classe proxy // ihello hello = hello (); // se não precisarmos de assassinato, que não precisamos de login (use a. Depois de ler o código acima, pode haver um problema em comparação com a Spring AOP. A classe de log só pode ser impressa antes e depois do método, mas a AOP deve poder executar quando as condições forem atendidas. Todo o objeto Dynapoxyhello e o objeto de operação de log (Logger) pode ser dissociado?
Olhando para a seguinte implementação de código, ele dissociará o objeto Dynapoxyhello e o objeto de operação de log (Logger):
Precisamos adicionar código de operação de log (ou outro código de operação) antes ou depois do método do objeto proxy. Em seguida, podemos abstrair uma interface, que possui apenas dois métodos: um é o método executado antes do objeto proxy querer executar o método. Nomeamos o Start, e o segundo método é o método executado após o objeto Proxy executar o método, e nomeamos o final.
Interface do Logger:
interface pública ilogger {void start (método do método); vazio final (método método);} Implementação da interface do logger:
public class DLogger implementa ILOGGER {@OverridePublic void START (método do método) {System.out.println (new Date () + Method.getName () + "Say Hello Start ...");}@EverridePublic void end (Método) {System.out.println (date () + Método.get.genn (Métodonn) (Método) (Método) (Método) () () ()}} método. Classe de proxy dinâmica:
public class dynaproxyhello implementa a InvocationHandler {// CHAMADO DE Objeto Private Object Proxy; // Target Object Private Object Target; Public Object Bind (Object Target, Object Proxy) {this.Target = Target; this.Proxy = proxy; Return proxy.NewProxyInser (this.target.getcly. this.target.getclass (). getInterfaces (), this);}@substituir o objeto de substituto (proxy de objeto, método, método, objeto [] args) lança arremesso {objeto resultado = null; // reflexão obtém a classe do operador, o metelete do operador. Classe [] {Method.class}); // A reflexão executa o método iniciante start.invoke (this.proxy, new Object [] {this.proxy.getclass ()}); // executa o método original para processar o método do objeto. Classe [] {Method.class}); // A reflexão executa o método final end.invoke (this.proxy, novo objeto [] {Method}); Return Result;}} Código de teste:
public class dynatest {public static void main (string [] args) {ihello hello = (ihello) new dynaProxyhello (). bind (new hello (), new dLogger ()); // se precisarmos da função de log, use a classe proxy // function, hello = new (); // se não precisarmos de login. Olá.sayhello ("amanhã");}} Através do exemplo acima, podemos descobrir que, através da tecnologia dinâmica de proxy e transmissão, a função da AOP foi basicamente implementada. Se precisarmos imprimir apenas o log antes que o método seja executado, não podemos implementar o método End (), para que possamos controlar o tempo de impressão. Se desejarmos o método especificado para imprimir o log, precisamos adicionar apenas um julgamento sobre o nome do método ao método Invoke (). O nome do método pode ser gravado no arquivo XML, para que possamos dissociá -lo com o arquivo de configuração, para que implementemos uma estrutura simples de Spring AOP.
O conteúdo acima é o princípio de implementação da Spring AOP introduzido pelo editor. Espero que seja útil para você!