1. Modo de agente
O modelo de proxy é chamado proxy ou substituto em inglês, e ambos podem ser traduzidos como "agente" em chinês. A chamada procuração significa que uma pessoa ou uma instituição age em nome de outra pessoa ou de outra instituição. Em alguns casos, um cliente não deseja ou não pode se referir diretamente a um objeto, e o objeto proxy pode atuar como um intermediário entre o cliente e o objeto de destino.
Explique as diferenças entre vários agentes, simulando o processo de execução das transações
1.1 Proxy estático
O código -fonte é criado por programadores ou gerado automaticamente por ferramentas específicas e depois compilado. Antes da execução do programa, já existe o arquivo .class da classe proxy.
interface pública Persondao {void savePerson ();} classe pública persondaoiMpl implementa Persondao {@Override public void SavePerson () {System.out.println ("salvar pessoa"); }} public class Transaction {void BeginTransaction () {System.out.println ("Begin Transaction"); } void Commit () {System.out.println ("Commits"); }}Em seguida, escreva uma aula de proxy estática-implemente a interface Persondao
/*** Classe de proxy estática* @author qjc*/public class PERSONDAOPROXY implementa Persondao {persondao persondao; Transação de transação; PERSONDAOPROXIA PÚBLICA (PERSONDAO PERSONDAO, TRANSACIONAÇÃO) {this.persondao = persondao; this.Transaction = transação; } @Override public void savePerson () {this.transaction.BegIntransaction (); this.persondao.saveperson (); this.Transaction.Commit (); }}teste
/*** Teste proxy estático* @author qjc*/public class TestPersonProxy {@Test public void testSave () {persondao persondao = new persondaoimpl (); Transação transação = new transaction (); Persondaoproxy proxy = new persondaoproxy (persondao, transação); proxy.saveperson (); }}Resumir:
1. O modo estático de proxy não reutiliza transações
2. Suponha que haja 100 classes e 100 proxy. Quantos métodos existem na interface, quantos métodos devem ser implementados na camada proxy e quantas transações devem ser abertas e enviadas como tantos métodos.
3. Se um proxy implementa várias interfaces, se uma das interfaces mudar (um método for adicionado), o proxy também precisará mudar de acordo.
1.2 proxy dinâmico JDK
Classe de proxy dinâmica: é criada dinamicamente usando o mecanismo de reflexão quando o programa está em execução.
O proxy dinâmico do JDK deve atender a quatro condições: 1. Interface alvo 2. Classe de destino 3. Interceptador 4. Classe de proxy
Usando a interface Persondao, a classe Persondaoimpl e aula de transação no exemplo anterior
Escreva um interceptador
importar java.lang.reflect.invocationHandler; importar java.lang.reflect.method;/** * Interceptor * 1. Importar a classe de destino em * 2. Importar coisas em * 3. Invocar a conclusão: Iniciar transações; // Transação de transação privada da classe de destino; interceptador público (destino do objeto, transação de transação) {this.target = Target; this.Transaction = transação; } /** * @param proxy instance of the proxy class of the target object* @param method Corresponding to the Method instance that calls the interface method on the proxy instance* @param args The object array passed into the method parameter values on the proxy instance* @return The return value of the method, no return value is null * @throws Throwable */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {String MethodName = Method.getName (); if ("saveperson" .equals (MethodName) || "Deleteperson" .Equals (MethodName) || "UpdatePerson" .equals (MethodName)) {this.Transaction.BegIntransaction (); // Ativar método de transação.invoke (Target); // Ligue para o método de destino this.Transaction.Commit (); // Enviar transação} else {Method.inVoke (Target); } retornar nulo; }}teste
/*** Teste o proxy dinâmico JDK* @Author qjc*/public class TestJdkProxy {@Test public void testSave () {/*** 1. Crie um objeto de destino* 2. Crie uma transação* 3. Crie um interceptor* 4. Gerar dinâmico um proxy Transação transação = new transaction (); Interceptador interceptador = novo interceptador (destino, transação); /*** Parâmetro 1: Defina o carregador de classe usado pelo código, que geralmente usa o mesmo carregador de classe que o parâmetro 2 da classe de destino*: Defina a interface implementada pela classe Proxy e use a mesma interface que o parâmetro 3 do destino*: defina o objeto de retorno de chamada. Quando o método do objeto proxy for chamado, o método de invasão do objeto especificado será chamado*/ persondao persondao = (persondao) proxy.newproxyinstance (Target.getClass (). persondao.saveperson (); }}Resumir :
1. Como a classe proxy gerada pelo JDKProxy implementa a interface, todos os métodos na classe de destino estão incluídos na classe Proxy.
2. Todos os métodos da classe de proxy gerados intercepta todos os métodos da classe de destino. O conteúdo do método de invoque no interceptador é exatamente a composição de cada método da classe proxy.
3. As interfaces devem existir ao usar o JDKProxy.
4. Os três parâmetros no método Invoke podem acessar a API do método chamado, os parâmetros do método chamado e o tipo de retorno do método chamado da classe de destino.
deficiência:
1. No interceptador, exceto por chamar o método de destino do objeto de destino, a função é relativamente única. Neste exemplo, apenas transações podem ser processadas.
2. A declaração de julgamento IF do método de invasão no interceptador não é confiável em um ambiente de desenvolvimento real, porque, uma vez que existem muitas declarações se, ele precisa ser escrito.
1.3 Proxy dinâmico do CGLIB
Use a classe de transação e a classe de transação Persondaoimpl no exemplo anterior (sem interface)
Escreva aulas de interceptador
importação net.sf.cglib.proxy.enhancer; importação net.sf.cglib.proxy.methodintercept; importação net.sf.cglib.proxy.methodProxy;/*** cglib proxy interceptor* @author qjc*/public class Interceptor supletorMor MethodiSTORMOR {ATHOR @Author // Transação de transação privada da classe de alvo proxy; interceptador público (destino do objeto, transação de transação) {this.target = Target; this.Transaction = transação; } / ** * Crie o objeto proxy do objeto de destino * * @return * / public Object CreateProxy () {// Código ENCERMENT APRESENCER ENFERCHER = new Enhancer (); // Esta classe é usada para gerar o objeto proxy aprimorador.setCallback (this); // O parâmetro é o interceptor aprimorador.SetSuperclass (Target.getClass ()); // Defina a classe pai Return ENFERCHER.CRERECE (); // Crie um objeto proxy}/ *** @param obj instância da classe de proxy do objeto de destino* @param Método Instância do método que chama o método da classe pai na instância do proxy* @param args uma matriz de objetos passados para os valores de parâmetros do método* @MethodEsturn* @param @param MethodProxy Use -o para chamar o método da classe de classe* Args, MethodProxy Methodproxy) lança jogável {this.Transaction.BegIntransaction (); Method.inVoke (Target); this.Transaction.Commit (); retornar nulo; }}teste
/*** Teste o proxy dinâmico cglib* O objeto proxy gerado através do CGLIB, a classe Proxy é uma subclasse da classe de destino* @author qjc*/public class TestcglibProxy {@test public void testSave () {objeto destino = new PersondaoImpl (); Transação transação = new transaction (); Interceptador interceptador = novo interceptador (destino, transação); Persondaoimpl persondaoimpl = (persondaoImpl) interceptor.createproxy (); persondaoimpl.saveperson (); }}Resumir:
1. O CGLIB é uma biblioteca de classe de geração de código poderosa, de alto desempenho e de alta qualidade. Ele pode estender as aulas de Java e implementar interfaces Java durante o tempo de execução.
2. Use o CGLIB para gerar uma classe de proxy como uma subclasse da classe de destino.
3. Nenhuma interface é necessária para gerar classes de proxy usando CGLIB
4. A classe proxy gerada pelo CGLIB substitui os métodos da classe pai.
5. O conteúdo do método de interceptação no interceptador é exatamente a diferença entre o método do corpo CGLIB e o proxy dinâmico JDK na classe Proxy:
JDK:
A classe de destino e a classe proxy implementam uma interface comum
O interceptador deve implementar a interface InvocationHandler, e o conteúdo do corpo do método Invoke nessa interface é o conteúdo do corpo do método do objeto proxy.
CGLIB:
A classe de destino é a classe pai da classe de proxy
O interceptador deve implementar a interface MethodInterceptor, e o método de interceptação na interface é o corpo do método da classe proxy, e o mecanismo de aprimoramento do bytecode é usado para criar o objeto proxy.
2. Programação orientada orientada
OOP (programação orientada a objetos): encapsulamento, herança, polimorfismo, abstração
Encapsulamento, gerenciamento básico e modular do código. Cada classe pode ter suas próprias funções. Se algo der errado, procure alguém para discutir o assunto. Do ponto de vista da modificação, pode ser arriscado modificar o código diretamente. Esta não é uma solução de longo prazo. O mais natural é mudar do encapsulamento do tipo. No entanto, como integrar novos tipos e sistemas antigos, por isso é necessário estabelecer uma relação sanguínea entre as classes. Então este é o requisito de herança. Através da herança, você pode descobrir que essas classes estão relacionadas e há um relacionamento pai-filho entre eles. Então, com base na herança, os polimorfismos têm características decisivas. Portanto, acredita-se geralmente que a característica mais central da orientação a objetos é na verdade o polimorfismo. Os primeiros primeiros estão todos colocando as bases. O polimorfismo é o seu principal recurso. O método de reescrita na subclasse representa a extensão desse nível e pode ser integrado ao sistema antigo e pode funcionar normalmente. Esta é a reutilização desse nível, novos métodos, sistemas antigos, extensões e reutilização.
AOP (programação orientada para a seção):
A programação essencial é uma tecnologia que adiciona dinamicamente funções aos programas sem modificar o código -fonte por meio de proxy dinâmico de tempo de execução pré -compilado.
Diferença entre OOP e AOP:
OPO: O encapsulamento abstrato é realizado nas entidades e suas propriedades e comportamentos do processo de processamento de negócios para obter uma divisão mais clara de unidades lógicas.
AOP: extrai a lógica cruzada no processo de negócios. Ele enfrenta uma certa etapa ou estágio no processo para obter o baixo efeito de isolamento de acoplamento entre as partes do processo lógico. Essas duas idéias de design têm diferenças essenciais nos objetivos. AOP alcançou a reutilização de blocos de código.
Mecanismo de proxy da Spring AOP:
1. Se o objeto de destino implementar várias interfaces, o Spring usará o proxy Java.Lang.Reflect.Proxy da JDK.
Vantagens: como há uma interface, o sistema é mais frouxo
Desvantagens: Crie interfaces para cada classe de destino
2. Se o objeto de destino não implementar nenhuma interface, o Spring usará a biblioteca CGLIB para gerar uma subclasse do objeto de destino.
Vantagens: como a classe de proxy e a classe de destino são herdadas, não há necessidade de uma interface existir.
Desvantagens: Como não há interface usada, o acoplamento do sistema não é tão bom quanto o proxy dinâmico usando o JDK.
Usando a interface Persondao, a classe persondaoimpl e a classe de transação
Escreva a configuração da primavera
<bean id = "persondao"> </i bean> <bean id = "transaction"> </bean> <AOP: config> <!-expressão de ponto de ponto determina a classe de destino-> <aOP: Pointcut Expression = "Execution (* cn.qjc.aop.xml.PersandAoMpl. <AoP: aspecto ref = "transação"> <aOP: antes do método = "BeginTransaction" Pointcut-ref = "Perform"/> <AOP: Método de Retireção Após a Retireção "Pointcut-Ref =" Perform "/> </AOP: Aspect> </AOP: Config> </i Beans>
teste
/*** Proxy dinâmico da mola de teste* @author qjc*/public class TransactionTest {@Test public void testSave () {ApplicationContext context = new ClassPathXMLApplicationContext ("CN/QJC/AOP/XML/ApplicationContext.xml"); Persondao persondao = (persondao) context.getbean ("persondao"); persondao.saveperson (); }}Princípio da AOP da primavera
1. Quando o recipiente de mola é iniciado, dois feijões são carregados e instanciados.
2. Quando o contêiner de mola analisar o arquivo de configuração para <aOP: config>, analise a expressão de corte de pontos e corresponda aos grãos do conteúdo do contêiner de mola de acordo com a expressão de corte de ponto.
3. Se a partida for bem -sucedida, crie um objeto proxy para o feijão
4. Quando o cliente usa o context.getBean para obter um objeto, se o objeto tiver um objeto proxy, ele retornará o objeto Proxy. Se não houver objeto de proxy, ele retornará o próprio objeto.
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.