Se a classe proxy já existir antes da execução do programa, esse método de proxy será chamado de proxy estático. Nesse caso, a classe proxy geralmente é definida no código Java. Normalmente, a classe de proxy e a classe delegada no proxy estático implementam a mesma interface ou são derivados da mesma classe pai.
1. Visão geral
1. O que é um agente
Todos sabemos que os agentes da WeChat estão simplesmente vendendo mercadorias em nome dos fabricantes, e o fabricante "confiou" agentes para vender mercadorias para eles. Em relação aos agentes de negócios do WeChat, antes de tudo, quando compramos coisas deles, geralmente não sabemos quem é o fabricante, ou seja, o "Comissário" é invisível para nós; Em segundo lugar, os agentes de negócios da WeChat têm como alvo principalmente as pessoas no círculo de amigos como seus clientes, o que equivale a um "filtro" do grupo de clientes para o fabricante. Resumimos ainda o agente e fabricante de micro-negócios. O primeiro pode ser abstraído como uma classe de agente, e o último pode ser abstraído como uma classe de delegados (classe do agente). Ao usar um proxy, geralmente existem duas vantagens e podem corresponder às duas características do agente de micro-negócios que mencionamos:
Vantagem 1: ele pode ocultar a implementação da classe Delegate;
Vantagem 2: Ele pode alcançar a dissociação entre o cliente e a classe Delegate e pode fazer algum processamento adicional sem modificar o código de classe Delegate.
2. Proxy estático
Se a classe proxy já existir antes da execução do programa, esse método de proxy será chamado de proxy estático. Nesse caso, a classe proxy geralmente é definida no código Java. Normalmente, a classe de proxy e a classe delegada no proxy estático implementam a mesma interface ou são derivados da mesma classe pai. Abaixo, usamos a classe de fornecedores para representar o fabricante e a classe BusinessAgent para representar o agente de microempreências para introduzir a simples implementação de agentes estáticos. A classe de delegação e a classe proxy implementam a interface de venda. A definição da interface de venda é a seguinte:
interface pública Sell {void Sell (); vazio ad (); } A definição da classe de fornecedores é a seguinte: Public Class Forneceds implementos de venda {public void Sell () {System.out.println ("no método de venda"); } public void ad () {System, out.println ("ad método")}} A definição da classe proxy BusinessAgent é a seguinte:
Public class fornecendo implementos de venda {public void Sell () {System.out.println ("no método de venda"); } public void ad () {System, out.println ("ad método")}} A partir da definição da classe BusinessAgent, podemos entender que os agentes estáticos podem ser implementados por meio de agregação, para que a classe do agente possa manter uma referência à classe Delegate.
Vamos considerar esse requisito abaixo: adicione uma função de filtragem à aula de fornecedores e vender mercadorias apenas para estudantes universitários. Através do proxy estático, podemos alcançá -lo sem modificar o código da classe de fornecedores. Só precisamos adicionar um julgamento ao método de venda na classe BusinessAgent e pode ser o seguinte:
public class BusinessAgent implementos vender {... public void Sell () {if (isCollegestudent ()) {vendor.sell (); }} ...} Isso corresponde à segunda vantagem do uso de um proxy mencionado acima: ele pode alcançar a dissociação entre o cliente e a classe Delegate e pode fazer algum processamento adicional sem modificar o código de classe Delegate. A limitação do proxy estático é que você deve escrever uma aula de proxy antes de executar. Vamos nos concentrar na introdução do método dinâmico de proxy de gerar classes de proxy em tempo de execução.
2. Agente dinâmico
1. O que é proxy dinâmico
O método proxy criado pela classe Proxy quando o programa é executado é chamado de proxy dinâmico. Ou seja, neste caso, a classe proxy não é definida no código Java, mas é gerada dinamicamente em tempo de execução com base em nossas "instruções" no código Java. Comparado ao proxy estático, a vantagem do proxy dinâmico é que ele pode facilmente lidar com funções da classe proxy uniformemente sem modificar as funções de cada classe de proxy. Isso é mais abstrato. Vamos combinar um exemplo para introduzir como as vantagens do proxy dinâmico são refletidas.
Agora, suponha que queremos implementar o requisito: saída "antes" antes de executar o método na classe Delegate e a saída "após" após a execução. Apresentaremos a classe de fornecedores como a classe Delegate no exemplo acima e a classe BusinessAgent como a classe de procuração. Primeiro, vamos usar um proxy estático para atingir esse requisito. O código relevante é o seguinte:
Public class BusinessAgent implementos vendem {MVENDOR DE VENDENTE PRIVADO; public BusinessAgent (fornecedor do fornecedor) {this.mvendor = fornecedor; } public void Sell () {System.out.println ("Antes"); mvendor.sell (); System.out.println ("After"); } public void ad () {System.out.println ("antes"); mvendor.ad (); System.out.println ("After"); }} A partir do código acima, podemos entender que a implementação de nossas necessidades através do proxy estático exige que adicionemos lógica correspondente a cada método. Existem apenas dois métodos aqui, portanto a carga de trabalho não é grande. E se a interface de venda contiver centenas de métodos? Neste momento, o uso de proxy estático escreverá muito código redundante. Ao usar proxy dinâmico, podemos fazer uma "indicação uniforme" para processar uniformemente os métodos de todas as classes de proxy sem modificar cada método um por um. Vamos introduzir como usar o proxy dinâmico para implementar nossas necessidades.
2. Use proxy dinâmico
(1) Ao usar proxy dinâmico na interface InvocationHandler, precisamos definir uma classe intermediária localizada entre a classe Proxy e a classe Delegate. Esta classe intermediária é necessária para implementar a interface InvocationHandler. A definição dessa interface é a seguinte:
Public Interface InvocationHandler {Object Invoke (proxy do objeto, método do método, objeto [] args); } A partir do nome InvocationHandler, podemos saber que a classe de mediação que implementa essa interface é usada como o "processador de chamada". Quando chamamos o método do objeto de classe proxy, essa "chamada" será encaminhada para o método Invoke. O objeto de classe proxy é passado como um parâmetro proxy. O método do parâmetro identifica qual método chamamos de classe proxy. Args é o parâmetro deste método. Dessa forma, nossas chamadas para todos os métodos na classe Proxy se tornarão chamadas para invocar, para que possamos adicionar a lógica de processamento unificado ao método Invoke (ou diferentes métodos da classe Proxy podem ser processados de acordo com os parâmetros do método). Portanto, precisamos apenas produzir "antes" na implementação do método Invoke da classe de mediação, depois chamar o método de invocar a classe Delegate e depois a saída "após". Vamos implementá -lo passo a passo.
(2) Sob o método dinâmico de proxy da classe Delegate, a classe Delegate deve implementar uma determinada interface. Aqui implementamos a interface de venda. A definição da classe do fornecedor é a seguinte:
Public class fornecendo implementos de venda {public void Sell () {System.out.println ("no método de venda"); } public void ad () {System, out.println ("ad método")}} (3) Classe de mediação, como mencionado acima, a classe de mediação deve implementar a interface InvocationHandler, pois o processador de chamadas "intercepta" chama para os métodos de classe de proxy. A definição da classe intermediária é a seguinte:
classe pública DynamicProxy implementa InvocationHandler {objeto privado obj; // Obj é um objeto de classe delegado; public dynamicproxy (objeto obj) {this.obj = obj; } @Override Public Object Invoke (proxy do objeto, método do método, objeto [] args) lança arremesso {System.out.println ("antes"); Resultado de objeto = method.invoke (obj, args); System.out.println ("After"); resultado de retorno; }} A partir do código acima, podemos ver que a classe intermediária possui uma referência de objeto delegado, e o método correspondente do objeto delegado é chamado no método Invoke (linha 11). Você acha que parece familiar quando vê isso? Mantendo a referência do objeto delegado através do método de agregação, convertendo todas as chamadas externas para invocar em chamadas para o objeto delegado. Não é um método de proxy estático de implementação que introduzimos acima? De fato, a classe intermediária e a classe delegada formam uma relação proxy estática. Nesse relacionamento, a classe intermediária é uma classe de proxy, e a classe Delegate é uma classe de delegação; A classe de proxy e a classe intermediária também formam uma relação proxy estática. Nesse relacionamento, a classe intermediária é uma classe de delegação e a classe de proxy é uma classe de proxy. Em outras palavras, o relacionamento dinâmico de proxy consiste em dois conjuntos de relações estáticas de proxy, que é o princípio do proxy dinâmico. Vamos introduzir como "instruir" gerar dinamicamente classes de proxy.
(4) Classe de proxy de geração dinâmica Classe de proxy Dinâmica Os códigos relevantes são os seguintes:
classe pública principal {public static void main (string [] args) {// Crie uma instância da classe de mediação dinâmicaProxy inter = new DynamicProxy (new Vendor ()); // Adicione esta frase gerará um arquivo $ proxy0.class, que é o arquivo de classe de proxy gerado dinamicamente o sistema de arquivo.getProperties (). Put ("sun.misc.proxygenerator.SaveGeneratedFiles", "True"); // obtenha a classe Proxy Instância Sell Sell Sell = (Sell) (proxy.newproxyInstance (Sell.class.getClassLoadeler (), nova classe [] {Sell.class}, inter)); // chamando o método da classe proxy por meio do objeto de classe proxy realmente irá para o método Invoke para chamar Sell.sell (); Sell.ad (); }} No código acima, chamamos o método NewProxyInstance da classe Proxy para obter uma instância da classe proxy. Essa classe de proxy implementa a interface que especificamos e distribuirá chamadas de método para o processador de chamada especificado. A declaração deste método é a seguinte:
Copie o código da seguinte
Os três parâmetros do método são os seguintes:
carregador: define o cloder da classe de proxy;
Interfaces: Lista de interfaces implementadas pela Classe de Proxy
H: Ligue para o processador, ou seja, a instância da classe que definimos acima que implementa a interface InvocationHandler, vamos executá -la para ver se nosso proxy dinâmico pode funcionar corretamente. A saída que eu corro aqui é:
Isso mostra que nosso proxy dinâmico está realmente funcionando.
Mencionamos brevemente o princípio da proxy dinâmica acima. Aqui resumiremos brevemente: Primeiro, podemos obter a instância da classe proxy através do método NewProxyInstance e, em seguida, podemos chamar o método da classe proxy por meio desta instância da classe proxy. No método da classe proxy, chamaremos o método Invoke da classe de mediação (chamado de processador). No método Invoke, chamamos o método correspondente da classe Delegate e podemos adicionar nossa própria lógica de processamento.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.