O modo proxy usa o objeto proxy para concluir a solicitação do usuário e bloqueia o acesso do usuário ao objeto real.
O modo proxy tem muitos usos, como por razões de segurança, é necessário impedir que o cliente acesse diretamente o objeto real; ou em chamadas remotas, o objeto proxy precisa ser usado para lidar com detalhes técnicos no método remoto; ou para melhorar o sistema, o objeto real é encapsulado para alcançar o objetivo do atraso no carregamento.
Quando o sistema inicia, separar o método que consome o máximo de recursos usando o modo proxy pode acelerar a velocidade de inicialização do sistema e reduzir o tempo de espera do usuário. Quando o usuário está realmente fazendo consulta, a classe Proxy carrega a classe real para concluir a solicitação do usuário. Esse é o objetivo de usar o modo proxy para obter carregamento preguiçoso.
1. Implementação estática de proxy:
Interface de tópico:
interface pública IdBQuery {String request (); } Tópico real:
classe pública dbQuery implementa o IdbQuery {public dbQuery () {try {thread.sleep (10000); } catch (Exceção e) {e.printStackTrace (); }} public string request () {return "string request"; }} Classe de proxy:
classe pública IdbQueryProxy implementa Idbquery {private dbQuery dbQuery; public string request () {if (dbQuery == null) dbQuery = new DBQuery (); retornar dbQuery.Request (); }} Finalmente, a função principal:
classe pública proxytext {public static void main (string [] args) {iDBQuery dbQuery = new iDBQueryProxy (); System.out.println (dbQuery.Request ()); }}Proxy estático Observe que a classe de proxy é uma interface comum para as classes reais implementarem, e a classe proxy se refere a objetos de classe real e coloca operações demoradas no método da classe proxy para implementá-lo.
Proxy dinâmico:
O proxy dinâmico é quando a execução gera dinamicamente as classes de proxy. Ou seja, o bytecode da classe proxy é gerado e carregado em tempo de execução. Comparados com agentes estáticos, os agentes dinâmicos não precisam ter cuidado para encapsular uma classe de encapsulamento completamente idêntica para o objetivo real. Se houver muitas interfaces de tópicos, é irritante escrever um método proxy para cada interface. Se a interface mudar, a classe real e a classe de proxy precisam ser alteradas, o que não é propício à manutenção do sistema; Em segundo lugar, os métodos de geração de alguns agentes dinâmicos podem até ser executados em tempo de execução, que é uma lógica de execução de classe de proxy especificada, melhorando bastante a flexibilidade do sistema.
Interface de tópico:
interface pública IdBQuery {String request (); } Classe de proxy JDK:
classe pública jdbdbqueryhandler implementa InvocationHandler {iDBQuery iDBQuery = null; @Override Public Object Invoke (proxy do objeto, método do método, objeto [] args) lança Throwable {if (iDBQuery == null) {iDBQuery = new DBQuery (); } return iDBQuery.Request (); } public static idbQuery createjdbProxy () {IdBQuery jdkProxy = (iDBQUERY) proxy.newproxyInstance (classloader.getSystemclassloader (), nova classe [] {iDBQUERY.Class}, novo jdbdbQuherHandler (); System.out.println ("jdbdbqueryHandler.createjdbproxy ()"); retornar jdkproxy; }} Função principal:
classe pública proxytext {public static void main (string [] args) {iDBQuery iDBQuery = jdbdbQueryHandler.createjdbProxy (); System.out.println (iDBQuery.Request ()); }}Além disso, você também pode usar o proxy dinâmico CGLIB e Javassist para ser semelhante ao proxy dinâmico do JDK, mas o processo de criação da classe dinâmica JDK é o mais rápido, porque o método DiFineClass () interno é definido como uma implementação nativa, portanto seu desempenho é melhor que outros. Nas chamadas de função das classes de proxy, o proxy dinâmico do JDK não é tão bom quanto o proxy dinâmico do CGLIB e do Javassista, enquanto o proxy dinâmico do Javassist tem a pior qualidade de desempenho e é ainda pior que a implementação do JDK. Nas aplicações reais de desenvolvimento, a frequência de chamada de método da classe de proxy é muito maior que a frequência de geração real da classe de proxy; portanto, o desempenho de chamadas de método de proxy dinâmico deve se tornar o foco do desempenho. O proxy dinâmico do JDK exige que as classes de proxy e tópicos reais implementem interfaces unificadas, e o CGLIB e o proxy dinâmico Javassist não têm esses requisitos.
Em Java, a implementação do proxy dinâmico envolve o uso do carregador de classe. Tomando o CGLIB como exemplo, é descrita uma breve descrição do processo de carregamento das classes dinâmicas. Usando o CGLIB para gerar proxy dinâmico, primeiro você precisa gerar uma instância da classe Enhancer e formular uma classe de retorno de chamada para lidar com negócios de procuração. No método intensancer.create (), o bytecode da classe proxy será gerado usando o método defaultGeneratorStrategy.Generate () e salvo na matriz de bytes. Em seguida, chame o método refletUtils.DefineClass () e, por meio de reflexão, ligue para ClassLoader.DefineClass () para carregar o bytecode no carregador de classe para concluir o carregamento da classe. Finalmente, através do método refletiTULS.NewInstance (), uma instância de classe dinâmica é gerada pela reflexão e a instância é retornada. Outros são diferentes dos detalhes do processo, mas a lógica de geração é a mesma.
O exposto acima é tudo sobre este artigo, espero que seja útil para o aprendizado de todos.