Noções básicas: requer idéias de design orientadas a objetos, idéias polimórficas e idéias de reflexão;
O surgimento do mecanismo de proxy dinâmico Java permite que os desenvolvedores de Java obtenham dinamicamente as classes de proxy sem precisar escrever manualmente as classes de procuração. A classe de proxy é responsável por despachar todas as chamadas de método para o objeto Delegado para refletir a execução. Durante o processo de execução de despacho, os desenvolvedores também podem ajustar o objeto delegado e suas funções, conforme necessário. Esta é uma estrutura de proxy muito flexível e flexível. Ao ler este artigo, os leitores terão uma compreensão mais profunda do mecanismo de proxy dinâmico de Java. Este artigo analisa primeiro o código com base no mecanismo operacional e nas características do proxy dinâmico Java e deduz a implementação interna de classes de geração dinâmica.
Conceitos básicos e classificação do modelo de agente
Modo proxy: fornece um proxy para outros objetos controlarem o acesso a esse objeto. O objeto proxy atua como intermediário e pode remover serviços ou adicionar serviços adicionais ou citar outros: "A classe de proxy é responsável por pré-processamento de mensagens para a classe Delegate, filtrar mensagens e encaminhar mensagens e executar o processamento subsequente após a execução da mensagem pela classe delegada".
Cenários de aplicação do modo de agente no desenvolvimento
Proxy remoto: fornece objetos representativos da LAN para objetos de diferentes regiões geográficas.
Agente virtual: atrasar objetos que consomem muitos recursos conforme necessário e os criam quando forem realmente necessários. Por exemplo, o texto é exibido primeiro e, em seguida, a imagem é exibida na página da web.
Agente de proteção: controla os direitos de acesso de diferentes usuários. Por exemplo: Somente após o sucesso do registro do cliente pode adicionar, excluir, modificar e verificar as operações de verificação.
Agente de referência inteligente: fornece serviços adicionais ao agente de destino.
Como implementar o modo proxy
Qual é melhor implementar proxy dinâmico usando herança e agregação!
interface pública móvel {public void move ();} classe pública Carro implementa móvel {@Override public void move () {try {thread.sleep (new Random (). nextInt (1000)); System.out.println ("... dirigindo ...");} Catch (interruptException e) {/wdo autO automático Car2 estende o carro {@Override public void move () {// separa o código, aumente a lógica de negócios long startTime = system.currenttimemillis (); system.out.println ("o carro começa a dirigir ..."); super.move (); endtime = system.curntimlesting para drive (); "+(Endtime-starttime)+" ms ");}}Método de herança para implementar proxy
Moveablecar2=newCar2();
car2.move();
O método de agregação implementa proxy
Carcar=newCar();
Moveablem=newCar3(car);
m.move();
Resumir
O método de herança não é flexível o suficiente. Quando as funções são sobrepostas, você só pode expandir a classe proxy inchaço;
Usando agregação, os agentes podem ser transmitidos um ao outro e um proxy pode ser combinado com flexibilidade;
classe pública CarLogProxy estende o carro {@Override public void move () {// Separe o código e aumente a lógica de negócios long startTime = System.currenttimemillis (); System.out.println ("Login Start ..."); Super.Move (); Long Endtime = System.CurrinMillis (); System.out.out.out.Move ();); CartimeProxy implementa móveis {public CartimeProxy (carro do carro) {super (); this.car = carro;} carcar privado; @Override public void move () {// separa o código e adiciona lógica de negócios long starttime = system.currenttimEmillis (); system.out.println ("carar de carro ... endtime = system.currenttimemillis (); system.out.println ("O carro termina para dirigir ... tempo:"+(final de partida de final)+"ms");}}@teste: car car = carlogProxy cloGpProxy ctp = new CartimeProxy (carl); carlogProxy clappProxy; Instâncias de proxy entre si por meio de interfaces CarLogProxy clp1 = new CarLogProxy (CAR); CartimeProxy ctp1 = new CartimeProxy (CLP1); ctp1.move ();Proxy dinâmico JDK e proxy dinâmico CGLIB
JDK Proxy dinâmico
Implementação do agente
O que deve ser feito se diferentes objetos desejarem implementar a classe Proxy com a mesma função?
No momento, você pode tentar integrá-lo na mesma classe de proxy ------- Proxy dinâmico: implementar proxy para diferentes classes/métodos diferentes;
O processo geral é o seguinte:
A classe de proxy dinâmica Java está localizada no pacote java.lang.reflect, que geralmente envolve principalmente as duas classes a seguir:
(1) InterfaceInvocationHandler: apenas um método é definido nesta interface publicObjectinVoke (ObjectObj, MethodMethod, objeto [] args)
OBJ: Geralmente se refere à aula de proxy
Método: é o método de proxy
O ARGS é uma variedade de parâmetros para este método.
Este método abstrato é implementado dinamicamente na classe de proxy.
(2) Proxy: esta classe é uma aula de proxy dinâmica
statixObjectnewProxyInstance(ClassLoaderloader,Class[]interfaces,InvocationHandlerh)
Retorna uma instância da classe glicosídeo e a classe de proxy retornada pode ser usada como a classe proxy (você pode usar o método declarado na interface pela classe Proxy);
Exemplo de implementação:
@ TimeHandler public class TimeHandler implementa InvocationHandler {public timeHandler (objeto alvo) {super (); this.Target = Target;} Private ObjectTarget;/** Parâmetros:* Proxy proxy objeto* Método do objeto de proxy Objeto* Args Parameter* Return Valor:* Objeto Retorno Retorno*/@ Surride startTime = system.currenttimemillis (); system.out.println ("o carro começa a dirigir ..."); method.invoke (Target); long Endtime = system.currenttimemillis (); system.out.println ("o carro termina para dirigir ... time:"+(finalttime-start)+"ms"); @A interface da classe Proxy Public Interface Moverable {public void move ();}@a classe proxy public class Car CAR implementa móveis {@Override public void move () {try {thread.sleep (new Random (). NextInt (1000)); System.out.println ("... dirigindo ...");} Catch (interrupteDexception e) {// TODO GATO AUTO-GENERADO E.PrintStackTrace ();@teste
classe pública Test { / *** JDK Dinâmico Classe de teste de proxy* / public static void main (string [] args) {carro car = novo carro (); InvocationHandler H = novo TimeHandler (carro); Classe <?> Cls = car.getclass (); /** carregador carregador carregador* interfaces de implementação da interface* h InvocationHandler*/ MOVELIVE M = (MOVELECT) proxy.NewProxyInstance (cls.getclassloader (), cls.getInterfaces (), h); M.Move (); }}&& Resultados do teste
Resumo
O DynamicProxy é uma classe:
É uma classe gerada em tempo de execução. Esta classe precisa implementar um conjunto de interfaces. Ao usar classes dinâmicas de proxy, a interface InvocationHandler deve ser implementada.
Etapas gerais para proxy dinâmico JDK
1. Crie uma classe que implemente a interface InvocationHandler, que deve implementar Invoke ()
2. Crie a classe de proxy e a interface
3. Chame o método estático do proxy para criar uma classe de proxy
NewProxyInstance (ClassLoaderloader, Class [] Interfaces, InvocationHandlerh)
4. Métodos de chamada através de proxy
Implementação de proxy dinâmico do CGLIB
Implementação do agente
@Introducing CGLIB-NODE-2.2.JAR PACOTO
@CglibProxy Intercept Class implementa o método da interface MethodIntercept: reescrever o método de interceptação
classe pública CGLIBProxy implementa MethodIntercept {private intensiverenhancer = new ENFENCER (); Public Object getProxy (classe cl) {// Defina a classe que cria a subclasse aprimorador.SetSuperclass (CL); ENFETTOL** INCLUTLATET INVEXTELTET INVEXTELTEMETT INVEXTEMETT INVEXTEMETT INVEXTEMETROTET INVEXTEMETROTEMETROTEMETT (CL); Método args* Instância de proxy da classe proxy**/@Substitua interceptação pública de objeto (objeto obj, método m, objeto [] args, métodproxy proxy) lança arremesso {system.out.println ("login start ..."); // a classe proxy da classe parental.invOUt.invokesuper (obes); nulo;}}@Proxy Class Train
classe pública Trem {public void move () {System.out.println ("O trem está dirigindo ..."); }}@Test Class
Public class Test { / *** CGLIBPROXY Dinâmica Classe de teste de proxy* / public static void main (string [] args) {cglibProxy proxy = new CGlibProxy (); Trem t = (trem) proxy.getProxy (Train.class); t.Move (); }}## Resultados do teste:
Resumo
Etapas gerais para implementar proxy dinâmico usando cglibProxy
1. Crie uma classe para implementar o método da interface, e substituir o método de interceptação
2. Crie uma aula de proxy
3. Ligue para o método personalizado da classe proxy para obter uma instância de proxy
4. Chame o método que precisa ser executado pela instância de proxy
Resumo comparativo
JDK Proxy dinâmico
1. Somente classes de proxy que implementam interfaces
2. As classes sem interface não podem implementar proxy dinâmico para JDK
Proxy dinâmico do CGLIB
1. Implementando proxy para aulas
2. Gere uma subclasse para a classe de destino da execução e use o método de interceptação da tecnologia para interceptar todas as chamadas dos métodos da classe pai.
Simular etapas de geração de agentes
Ideias:
Função de implementação: retorne o objeto de proxy através do NewProxyInstance do Proxy
1. Declare um pedaço de código -fonte (agente de geração dinâmica)
2. Compile o código -fonte (JDKCompileRapi) para gerar novas classes (classes de proxy)
3. Carregue esta classe na memória e gerar um novo objeto (objeto proxy)
4. Retorne o objeto de proxy
Melhorar a implementação dinâmica de proxy
Primeiro, obtemos o compilador do sistema, pegamos o gerenciador de arquivos através do compilador e, em seguida, obtemos o arquivo. O compilador executa a tarefa de compilação. Depois de concluir a compilação, carregamos o arquivo de classe no carregador de classe, obtemos a instância através do método do construtor e, em seguida, chamamos o NewInstance () para receber uma instância de um objeto.
(1) Obtenha o compilador javacompilercompiler = ToolSProvider.getSystemJavacompiler ();
(2) StandardJavafilemanagerfilemgr = Compiler.GetStandardFilemanager (nulo, nulo);
(3) obtenha o arquivo iterableunits = filemgr.getjavafileObjects (nome do arquivo);
(4) compilação compilação compilationtaskt = compiler.gettask (null, filemgr, null, null, null, null, unidades);
(5) Carregar na memória
ClassloadCl = ClassLoader.GetSystemClassLoader ();
Classc = cl.loadclass ("com.imooc.proxy. $ Proxy0");
(6) Construa uma instância através do construtor do objeto proxy
ConstrutorCtr = c.getConstructor (infce);
Ctr.NewInstance (NewCar ());
--------
Como mencionado acima, a lógica de negócios interna é codificada. Como implementar o proxy dinâmico real e a lógica de negócios designada dinamicamente?
1. Você precisa criar um processador de transações. Primeiro, você cria uma interface, ou seja, InvocationHandler. Para simular o JDK, o nome da interface é o mesmo que o nome do processador de transações JDK. Você também escreve um método chamado Invoke (), que é usado para representar um determinado método de um objeto para o processamento de negócios. Portanto, você precisa passar por um determinado objeto e o método do objeto como parâmetros do método Invoke (). Invoke (ObjectObJ, MethodMethod), o método usado como parâmetro para a reflexão Java, e este pacote precisa ser introduzido. Dessa forma, a interface InvocationHandler é concluída.
2. Crie classes de implementação de processamento de transações, como o TimerProxy, para implementar a interface InvocationHandler, para que a estrutura se torne
― - - - - --555S - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Você precisa passar no objeto de destino. Se você não tiver parâmetros, não poderá escrever parâmetros. Crie um método de construção de objetos proxy e inicialize o objeto de destino.
3. No método NewProxyInstance () da classe Proxy, além de usar a interface da classe de destino como um parâmetro, você também precisa passar pelo processador de transação e depois alterar a parte codificada do objeto de instância criada e usar o método do processador de transação para substituí-lo. A dificuldade está na emenda de cordas.
Resumir
Em nosso projeto, o padrão do agente tem seu próprio significado prático. Por exemplo, se quisermos ligar para uma classe sob um determinado pacote JAR, podemos adicionar alguma lógica de negócios especial antes de ligar para esta classe. Este método também é chamado de programação orientada para AOP. (Adicione funções adicionais sem alterar as funções originais.)
O exposto acima é toda a explicação detalhada do código de proxy dinâmico Java (padrão de design) neste artigo, espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!