Spring AOP vs AspectJ

178

Tenho a impressão de que o Spring AOP é melhor usado para tarefas específicas de aplicativos, como segurança, log, transações, etc., pois usa anotações Java5 personalizadas como estrutura. No entanto, o AspectJ parece ser mais amigável quanto aos padrões de design.

Alguém pode destacar os vários prós e contras do uso do Spring AOP vs AspectJ em um aplicativo Spring?

babydudecoder
fonte
3
Quando existe alguma anotação no Spring, mas também no Java, o que você deve usar? Java. A mesma lógica se aplica a essa funcionalidade. Primavera é Primavera. aqui hoje se foi amanhã. (As pessoas que se lembram usaram o Struts um pouco antes da primavera). AspectJ é a solução preferida a longo prazo. Durará mais que a primavera. Não estou demitindo Spring, apenas dizendo, por esse aspecto ...: -;
INOR

Respostas:

236

Profissionais do Spring-AOP

  • É mais simples de usar que o AspectJ, já que você não precisa usar LTW ( tecelagem em tempo de carregamento ) ou o compilador AspectJ.

  • Ele usa o padrão Proxy e o padrão Decorator

Contras Spring-AOP

  • Este é um AOP baseado em proxy, portanto, basicamente, você pode usar apenas pontos de junção de execução de método.
  • Aspectos não são aplicados ao chamar outro método dentro da mesma classe.
  • Pode haver um pouco de sobrecarga de tempo de execução.
  • O Spring-AOP não pode adicionar um aspecto a nada que não seja criado pela fábrica do Spring

AspectJ Pros

  • Isso suporta todos os pontos de junção. Isso significa que você pode fazer qualquer coisa.
  • Há menos sobrecarga de tempo de execução do que a Spring AOP.

AspectJ Cons

  • Seja cuidadoso. Verifique se os seus aspectos são tecidos apenas para o que você queria.
  • Você precisa de um processo de construção extra com o AspectJ Compiler ou precisa configurar o LTW (tecelagem em tempo de carregamento)
Whiteship
fonte
20
O @Configurable requer o uso do AspecJ via Spring. A partir de documentos:If you need to advise objects not managed by the Spring container (such as domain objects typically), then you will need to use AspectJ.
HDave
7
outra con primavera-aop para mim são as longas stacktraces ilegíveis por causa da abordagem baseada em proxy
wrm
1
Parte confusa da resposta: como é que ter um pequeno tempo de execução sobrecarrega um profissional para uma ferramenta e a possibilidade de um pouco de tempo de execução sobrecarregar um golpe para a outra?
Moreaki
16
@Moreaki: Ele disse 'um pouco de sobrecarga' como um golpe, e 'um pouco de sobrecarga' como um profissional. A única diferença 'a' é muito importante - em inglês, 'um pouco' significa 'alguns', enquanto 'pouco' significa 'quase nenhum'.
Wujek
1
Apenas uma dúvida rápida - em seus profissionais de Spring AOP (2º ponto) - se usarmos a anotação @Aspect na primavera, será um aspectoJ AOP, apenas imaginando, nesse caso, se ele usará proxy (tempo de execução) ou modificação de bytes (compile Tempo). Porque, tenho a impressão de que o AspectJ é tempo de compilação e o Spring AOP é o tempo de execução AOP. Pls ajuda
Pedantic
21

Além do que os outros afirmaram - apenas para reformular there are two major differences:

  1. Um está relacionado ao tipo de tecelagem.
  2. Outra para a definição do ponto de junção.

Spring-AOP: tempo de execução de tecelagem através de proxy usando o conceito dedynamic proxy if interface exists or cglib library if direct implementation provided.

AspectoJ: Tempo de compilação AspectJ Java Tools(ajc compiler)se a fonte estiver disponível ou pós-compilação (usando arquivos compilados). Além disso, a tecelagem do tempo de carregamento com o Spring pode ser ativada - ele precisa do aspectjarquivo de definição e oferece flexibilidade.

A tecelagem em tempo de compilação pode oferecer benefícios de desempenho (em alguns casos) e também a joinpoint definition in Spring-aop is restricted to method definition only which is not the case for AspectJ.

tecnologia
fonte
20

Uma observação adicional: se o desempenho sob alta carga for importante, você desejará o AspectJ que é 9 a 35x mais rápido que o Spring AOP . 10ns vs 355ns pode não parecer muito, mas já vi pessoas usando MUITOS Aspectos. 10K de aspectos. Nesses casos, sua solicitação pode atingir milhares de aspectos. Nesse caso, você está adicionando ms a essa solicitação.

Veja os benchmarks .

Joseph Lust
fonte
14

Spring AOP é uma das partes essenciais da estrutura da primavera. No estágio muito básico, a estrutura da primavera é baseada em IoC e AOP. No curso oficial da primavera, há um slide no qual diz:

A AOP é uma das partes mais importantes da estrutura.

O ponto principal para entender como a AOP no Spring funciona é que, quando você escreve um Aspect com Spring, instrumentamos a estrutura com a construção de um proxy para seus objetos, com a JDKDynamicProxyse o seu bean implementa uma interface ou via CGLIB se o seu bean não implementa nenhum interface. Lembre-se de que você deve ter o cglib 2.2 em seu caminho de classe se estiver usando o Spring anterior à versão 3.2. A partir do Spring 3.2, é inútil porque o cglib 2.2 foi incluído no núcleo.

A estrutura na criação do bean criará um proxy que agrupa seus objetos e adiciona responsabilidades de preocupações transversais, como segurança, gerenciamento de transações, registro e assim por diante.

A criação de proxy dessa maneira será aplicada a partir de uma expressão pointcut que instrui a estrutura a decidir quais beans e métodos serão criados como proxies. O conselho será mais responsável do que pelo seu código. Lembre-se de que, neste processo, o pointcut captura apenas métodos públicos que não são declarados como finais.

Agora, enquanto no Spring AOP, a tecelagem de Aspectos será realizada pelo contêiner na inicialização do contêiner, no AspectJ você deve fazer isso com uma pós-compilação do seu código através da modificação do bytecode. Por esse motivo, na minha opinião, a abordagem Spring é mais simples e mais gerenciável que a AspectJ.

Por outro lado, com o Spring AOP, você não pode usar todo o poder do AOP porque a implementação é feita por meio de proxies e não pela modificação do seu código.

Como no AspectJ, você pode usar a tecelagem em tempo de carregamento no SpringAOP. Você pode se beneficiar desse recurso na primavera, implementada com um agente e configurações especiais @EnabledLoadWeavingou em XML. Você pode usar o espaço para nome como um exemplo. No entanto, no Spring AOP, você não pode interceptar todos os casos. Por exemplo, o newcomando não é suportado no Spring AOP.

No entanto, no Spring AOP, você pode se beneficiar do uso do AspectJ usando o aspectofmétodo de fábrica no bean de configuração do Spring.

Pelo motivo de o Spring AOP ser basicamente um proxy criado a partir do contêiner, você pode usar o AOP apenas para spring beans. Enquanto estiver com o AspectJ, você pode usar o aspecto em todos os seus grãos. Outro ponto de comparação é a depuração e a previsibilidade do comportamento do código. Com o Spring AOP, o trabalho é pré-formado todo no compilador Java e os aspectos são uma maneira muito legal de criar proxy para o seu bean Spring. No AspectJ, se você modificar o código, precisará de mais compilação e entender onde seus aspectos estão entrelaçados pode ser difícil. Mesmo desligar a tecelagem na primavera é mais simples: com a primavera, você remove o aspecto da sua configuração, reinicia e funciona. No AspectJ, você deve recompilar o código!

Na tecelagem em tempo de carregamento, o AspectJ é mais flexível que o Spring, porque o Spring não suporta todas as opções do AspectJ. Mas, na minha opinião, se você deseja alterar o processo de criação de um bean, a melhor maneira é gerenciar o logon personalizado em uma fábrica e não com a tecelagem em tempo de carregamento de um aspecto que altera o comportamento do seu novo operador.

Espero que esta panorâmica do AspectJ e do Spring AOP ajude você a entender a diferença das duas poções

Valerio Vaudi
fonte
0

É importante considerar se seus aspectos serão de missão crítica e onde seu código está sendo implantado. O Spring AOP significa que você depende da tecelagem em tempo de carregamento. Isso pode falhar em tecer e, na minha experiência, significa que podem existir erros registrados, mas não impedirão a execução do aplicativo sem o código de aspecto [eu acrescentaria a ressalva de que talvez seja possível configurá-lo de tal maneira que esse não seja o caso; mas eu não estou pessoalmente ciente disso ]. A tecelagem em tempo de compilação evita isso.

Além disso, se você usar o AspectJ em conjunto com o aspectj-maven-plugin, poderá executar testes de unidade em relação aos seus aspectos em um ambiente de IC e ter confiança de que os artefatos construídos são testados e tecidos corretamente. Embora você possa certamente escrever testes de unidade acionados por Spring, você ainda não tem garantia de que o código implementado será aquele que foi testado se o LTW falhar.

Outra consideração é se você está hospedando o aplicativo em um ambiente em que é capaz de monitorar diretamente o sucesso ou falha de uma inicialização de servidor / aplicativo ou se o aplicativo está sendo implementado em um ambiente em que não está sob sua supervisão [por exemplo, onde é hospedado por um cliente]. Novamente, isso apontaria o caminho para compilar o tempo de tecelagem.

Há cinco anos, eu era muito mais favorável à AOP configurada pelo Spring pelo simples motivo de que era mais fácil trabalhar com e menos provável de mastigar meu IDE. No entanto, à medida que o poder de computação e a memória disponível aumentam, isso se torna muito menos problemático e a CTW com o aspectj-maven-plugin se tornou uma escolha melhor no meu ambiente de trabalho com base nos motivos que descrevi acima.

kcampbell
fonte
0

Este artigo também tem uma boa explicação sobre o tópico.

Spring AOP e AspectJ têm objetivos diferentes.

O Spring AOP visa fornecer uma implementação simples de AOP no Spring IoC para resolver os problemas mais comuns enfrentados pelos programadores.

Por outro lado, o AspectJ é a tecnologia original de AOP que visa fornecer uma solução completa de AOP.

gce
fonte
0

Comparado ao AOP, o AspectJ não precisa aprimorar a classe de destino no momento da compilação. Em vez disso, ele gera uma classe de proxy para a classe de destino no tempo de execução, que implementa a mesma interface que a classe de destino ou é uma subclasse da classe de destino.

Em resumo, uma instância de uma classe proxy pode ser usada como uma instância de uma classe de destino. Em geral, a estrutura AOP aprimorada em tempo de compilação é mais vantajosa em desempenho - porque a estrutura AOP aprimorada em tempo de execução requer aprimoramentos dinâmicos toda vez que é executada.

Jerry Hsu
fonte