1. Prefácio
Em projetos anteriores, raramente prestava atenção à implementação e teoria específicas da Spring AOP. Eu apenas entendi brevemente o que é AOP e como usá -lo. Eu vi um post que estava bem escrito, então vim aprender.
AOP
AOP (programação orientada para aspectos), ou seja, programação orientada a aspectos, pode-se considerar um suplemento e melhoria da OOP (programação orientada a objetos). A OOP apresenta conceitos como encapsulamento, herança e polimorfismo para estabelecer uma hierarquia de objetos que é usada para simular uma coleção de comportamento público. No entanto, o OOP permite que os desenvolvedores defina relacionamentos verticais, mas não é adequado para definir relacionamentos horizontais, como funções de registro. O código de log geralmente é disperso horizontalmente em todos os níveis de objeto e não tem nada a ver com as funções principais do objeto correspondente. Esse tipo de código não relacionado espalhado em todos os lugares é chamado de corte cruzado. No design da OOP, causa uma grande quantidade de duplicação de código, que não é propícia à reutilização de cada módulo.
A tecnologia AOP, pelo contrário, usa uma técnica chamada "corte cruzado" para dissecar o interior de um objeto encapsulado e encapsular os comportamentos comuns que afetam várias classes em um módulo reutilizável e nomeiam -o "aspecto", que é a faceta. A chamada "seção" é simplesmente encapsulada por lógica ou responsabilidades que não estão relacionadas ao negócio, mas são chamadas em conjunto pelo módulo de negócios, o que é conveniente para reduzir o código duplicado do sistema, reduzindo o acoplamento entre os módulos e conducente à futura operabilidade e manutenção.
Usando a tecnologia "Cross-Cutting", a AOP divide o sistema de software em duas partes: preocupação central e preocupaçã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 vários lugares, como autenticação de permissão, troncos e coisas. O papel da AOP é separar várias preocupações no sistema e separar as preocupações principais das preocupações cruzadas.
Conceito Core
1. Pontos de atenção cruzados
Quais métodos para interceptar e como lidar com isso após a interceptação? Essas preocupações são chamadas de preocupações cruzadas
2. Seção (aspecto)
As aulas são abstrações dos recursos dos objetos, e as seções são abstrações de preocupações cruzadas
3. Ponto de junho
O ponto interceptado, porque a primavera suporta apenas pontos de conexão do tipo método; portanto, o ponto de conexão na mola refere-se ao método interceptado. De fato, o ponto de conexão também pode ser um campo ou um construtor.
4. Pointcut
Definição de pontos de conexão intercepta
5. Notificação (conselho)
A chamada notificação refere-se ao código a ser executado após interceptar o ponto de conexão. As notificações são divididas em cinco categorias: notificações predefinidas, pós-set, exceção, final e circundantes.
6. Objeto alvo
O objeto alvo do proxy
7. TISE
O processo de aplicar uma fenda a um objeto de destino e causar criação de objetos proxy
8. Introdução
Sem modificar o código, a introdução pode adicionar dinamicamente alguns métodos ou campos à aula durante o período de tempo de execução
Apoio à Spring para AOP
O agente AOP na primavera é responsável pela geração e gerenciamento do contêiner do IOC da Spring, e suas dependências também são gerenciadas pelo contêiner do COI. Portanto, o proxy da AOP pode atingir diretamente outras instâncias de feijão no contêiner, e esse relacionamento pode ser fornecido pela injeção de dependência do contêiner do COI. As regras para criar um proxy na primavera são:
1. Por padrão, o proxy dinâmico Java é usado para criar proxy AOP, para que você possa criar proxy para qualquer instância da interface.
2. Quando a classe que precisa de um proxy não é uma interface proxy, o Spring muda para o uso de proxy do CGLIB e também pode forçar o CGLIB a usar.
A programação da AOP é realmente uma coisa muito simples. Olhando para a programação da AOP, os programadores precisam apenas participar de três partes:
1. Defina componentes de negócios comuns
2. Defina o ponto de entrada, um ponto de entrada pode cruzar vários componentes de negócios
3. Defina o processamento aprimorado. Processamento aprimorado é a ação de processamento que é tecida para componentes de negócios comuns na estrutura da AOP.
Portanto, a chave para a programação da AOP é definir o ponto de entrada e definir o processamento de aprimoramento. Depois que o ponto de entrada e o processamento de aprimoramento apropriados forem definidos, a estrutura da AOP gerará automaticamente um proxy da AOP, ou seja, o método do objeto proxy = Método de Processamento de Proxy de Proxy = Método de Proxy.
Aqui está um modelo de arquivo .xml da Spring AOP chamado AOP.xml, e o conteúdo subsequente é expandido no AOP.xml:
<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframwork.org/schemaop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> </ Beans>
Implementação simples da AOP baseada na primavera
Observe que, antes de explicar, deixe -me explicar: para executar o código com sucesso, não é suficiente usar o pacote JAR fornecido pela primavera ao desenvolvedor. Faça o download de dois pacotes de jar online:
1. AOPALLIANCE.JAR
2. AspectJweaver.jar
Vamos começar a explicar o método de implementação XML da Spring AOP, primeiro defina uma interface:
interface pública helloworld {void Primthelloworld (); DOPRINT VOID ();} Defina duas classes de implementação de interface:
classe pública helloworldImpl1 implementa o helloworld {public void Primthelloworld () {System.out.println ("Digite helloworldImpl1.printhelloworld ()"); } public void DOPRINT () {System.out.println ("Digite HelloworldImpl1.Doprint ()"); retornar ; }} classe pública helloworldImpl2 implementa o helloworld {public void Printhelloworld () {System.out.println ("Digite HelloworldImpl2.printhelloworld ()"); } public void DOPRINT () {System.out.println ("Digite helloworldImpl2.DoprInt ()"); retornar ; }} Foco cruzado, aqui está o tempo de impressão:
public class timeHandler {public void printTime () {System.out.println ("currentTime =" + System.CurrentTimEmillis ()); }} Com essas três classes, você pode implementar uma AOP de primavera simples. Dê uma olhada na configuração do AOP.xml:
<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframwork.org/schemaop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id =" helloworldImpl1 "/> <bean id =" helloworldImpl2 "/> <bEAN ID =" timeHandler "/> <coop: concht> id = "addallMethod" Expression = "Execution (* com.xrq.aop.helloworld.
Escreva uma função principal para chamá -lo:
public static void main (string [] args) {ApplicationContext ctx = new ClassPathXMLApplicationContext ("AOP.XML"); Helloworld hw1 = (helloworld) ctx.getbean ("helloworldImpl1"); Helloworld hw2 = (helloworld) ctx.getbean ("helloworldImpl2"); hw1.printhelloworld (); System.out.println (); hw1.doprint (); System.out.println (); System.out.println (); hw2.printhelloworld (); System.out.println (); hw2.doprint ();} O resultado em execução é:
CurrentTime = 1446129611993ENTER HELLOWORLDIMPL1.printhelloworld () CurrentTime = 1446129611993CurrentTime = 14461296119994ENTER HelloworldImpl1.Doprint () Currenttime = 144611196119944 Helloworldimpl2.printhelloworld () currenttime = 1446129611994CurrentTime = 14461296119994ENTER HELLOWORLDIMPL2.DOPRINT () CurrentTime = 1446129611994
Vi que todos os métodos das duas classes de implementação da interface helloworld foram adicionados ao proxy e o conteúdo de proxy é o tempo de impressão.
Detalhes adicionais sobre o uso de AOP baseado em primavera
1. Adicione uma preocupação cruzada e imprima o log. A aula de Java é:
public class LogHandler {public void LogBefore () {System.out.println ("log antes do método"); } public void LogAfter () {System.out.println ("Log após método"); }}<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframwork.org/schemaop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id =" helloworldImpl1 "/> <bean id =" helloworldImpl2 "/> <bean =" timeHandler "/> <Bean id =" LogHandler "" ref = "timeHandler" order = "1"> <aop: Pointcut id = "addtime" expressão = "Execution (* com.xrq.aop.helloworld. id = "log" ref = "logHandler" order = "2"> <aop: pointcut id = "printLog" expressão = "Execução (* com.xrq.aop.helloworld. </aOP: Aspect> </aOP: config> </ Beans>
A classe de teste permanece inalterada e o resultado da impressão é:
CurrentTime = 1446130273734Log Antes do método helloworldImpl1.printhelloworld () log após métodosCurrentTime = 1446130273735CurrentTime = 1446130273736Log Antes do método helloworldImpl1.Dent130 após o método do método do método do método do método do método do MetodCurnt. 1446130273736Log Antes do método helloworldImpl2.printhelloworld () registro após métodosCurrentTime = 1446130273736CurrentTime = 1446130273737Log Antes do método do helloworldImpl2.7777777737137130 Antes do método HelloworldImpl2.77777773737130 Antes do MetodENTER HelloworldImpl2.7 Log Após o método = 14446130 = 1446130 = 1446130 Antes do MetodENTER HELLOWORDIMPL2.7
Existem duas maneiras de usar o LogHandler antes do TimeHandler:
(1) Existe um atributo de ordem em aspecto, e o número do atributo de ordem é a ordem de corte cruzado dos pontos de foco
(2) Defina o LogHandler antes do TimeHandler. A primavera usa a ordem de definição de aspecto como a ordem de tecelagem por padrão.
2. Eu só quero tecer alguns métodos na interface
Basta modificar a expressão de Pointcut:
<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframwork.org/schemaop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id =" helloworldImpl1 "/> <bean id =" helloworldImpl2 "/> <bean =" timeHandler "/> <Bean id =" LogHandler "" ref="timeHandler" order="1"> <aop:pointcut id="addTime" expression="execution(* com.xrq.aop.HelloWorld.print*(..))" /> <aop:before method="printTime" pointcut-ref="addTime" /> <aop:after method="printTime" pointcut-ref="addTime" /> </aop:aspect> <aop:aspect id = "log" ref = "logHandler" order = "2"> <aop: pointcut id = "printLog" expressão = "Execução (* com.xrq.aop.helloworld.do* (..))" /> <aOp: antes do método = "LogBefore" Pointcut-ref = "PrintLog" /> <aop: " </aOP: Aspect> </aOP: config> </ Beans>
Isso significa que o TimeHandler tece apenas métodos que começam no início da interface Helloworld Print, o LogHandler só tecerá métodos que começam no início da interface Helloworld
3. Force CGLIB para gerar proxy
Como mencionado anteriormente, a Spring usa proxy ou CGLIB dinâmico para gerar proxy. As versões mais altas do Spring escolherão automaticamente se o uso de proxy ou cglib dinâmico para gerar conteúdo de proxy. Obviamente, também podemos forçar o CGLIB a gerar proxy, ou seja, existe um atributo de "classe proxy-alvo" em <AOP: config>. Se esse valor de atributo estiver definido como true, o proxy baseado em classe funcionará. Se a classe proxy-alvo estiver definida como falsa ou esse atributo for omitido, o proxy baseado em interface funcionará.
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.