j'ai écrit un aspect très simple avec Spring AOP. Cela fonctionne, mais j'ai du mal à comprendre ce qui se passe réellement. Je ne comprends pas pourquoi je dois ajouter le fichier aspectjweaver.jar? La documentation de Spring-AOP indique clairement que je n’ai pas besoin du compilateur ni du tisserand d’aspectj tant que j’utilise Spring-AOP:
Le runtime AOP est toujours un Spring AOP pur, et il n'y a aucune dépendance vis-à-vis du compilateur AspectJ ou du tisserand.
Ma configuration ressemble à ceci:
<aop:aspectj-autoproxy />
@Aspect
@Service
public class RemoteInvocationAspect {
@Before("execution(* at.test.mypackage.*.*(..))")
public void test() {
System.out.println("test");
}
...
J'ai aussi essayé la configuration XML, mais rien n'a changé. Peut-être que je pourrais simplement laisser tomber, mais j'aimerais vraiment comprendre pourquoi aspectj-weaver est utilisé? Si je n'ajoute pas la dépendance dans Maven, je reçois Java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
Je pense que la mise en œuvre de Spring AOP consiste à réutiliser certaines classes de l'aspectj-weaver. Il utilise toujours des procurations dynamiques - ne modifie pas le code d'octet.
Le commentaire commentaire suivant du forum de printemps pourrait clarifier.
Spring n'utilise pas le tisserand AspectJ dans ce cas. C'est simplement en réutilisant certaines des classes de aspectjweaver.jar.
-Ramnivas
J'ai récemment eu une question similaire Pourquoi Spring renvoie-t-il une erreur aspectj si elle ne dépend pas de aspectj?
Pour utiliser Spring AoP sans dépendance AspectJ, vous devez le faire en xml. Les annotations font partie de AspectJ.
En outre, le langage d’expression vraiment cool n’est pris en charge que par AspectJ. Vous devez donc définir des coupes de points explicites. Voir la section 6.3.2. Déclarer un point de coupe: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html section
J'ai encore du mal à trouver une documentation élaborée sur cette technique.
Vous utilisez le style AspectJ expression_du-point @Aspect
et @Before
font partie de AspectJ. Vérifiez ce lien .
En ce qui concerne le AspectJ-weaver
, il s’agit en fait d’un tisserand de type bytecode qui tresse des aspects en classes au moment du chargement.
Vous pouvez parcourir le site Web du printemps et trouver la réponse à la page de docs.spring.io
Le support @AspectJ peut être activé avec une configuration de style XML ou Java. Dans les deux cas, vous devrez également vous assurer que la bibliothèque Aspectjweaver.jar de AspectJ se trouve sur le chemin de classe de votre application (version 1.6.8 ou ultérieure). Cette bibliothèque est disponible dans le répertoire 'lib' d'une distribution AspectJ ou via le référentiel Maven Central.
Vous avez besoin des dépendances aspectjtools ou aspectjweaver lorsque vous utilisez le langage d’expression AspectJ.
S'il vous plaît voir les classes suivantes:
Foo.Java
public interface Foo {
void foo();
void baz();
}
FooImpl.Java
public class FooImpl implements Foo {
@Override
public void foo() {
System.out.println("Foo!");
}
@Override
public void baz() {
System.out.println("Baz!");
}
}
MethodBeforeAdviceBarImpl.Java
import org.springframework.aop.MethodBeforeAdvice;
import Java.lang.reflect.Method;
public class MethodBeforeAdviceBarImpl implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("Bar!");
}
}
Et s'il vous plaît voir App.Java version - 1
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.NameMatchMethodPointcutAdvisor;
public class App {
public static void main(String[] args) {
final MethodBeforeAdvice advice = new MethodBeforeAdviceBarImpl();
final NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor = new NameMatchMethodPointcutAdvisor();
nameMatchMethodPointcutAdvisor.setMappedName("foo");
nameMatchMethodPointcutAdvisor.setAdvice(advice);
final ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(nameMatchMethodPointcutAdvisor);
final Foo foo = new FooImpl();
proxyFactory.setTarget(foo);
final Foo fooProxy = (Foo) proxyFactory.getProxy();
fooProxy.foo();
fooProxy.baz();
}
}
Le résultat de l’exécution de cet exemple sera:
Bar!
Foo!
Baz!
J'ai seulement besoin de org.springframework: spring-context.jar dans mon classpath. Maintenant, au lieu d'un NameMatchMethodPointcutAdvisor, utilisons AspectJExpressionPointcutAdvisor:
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.aop.framework.ProxyFactory;
public class App {
public static void main(String[] args) {
final MethodBeforeAdvice advice = new MethodBeforeAdviceBarImpl();
final AspectJExpressionPointcutAdvisor aspectJExpressionPointcutAdvisor = new AspectJExpressionPointcutAdvisor();
aspectJExpressionPointcutAdvisor.setAdvice(advice);
aspectJExpressionPointcutAdvisor.setExpression("execution(void biz.tugay.spashe.Foo.foo())");
final ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(aspectJExpressionPointcutAdvisor);
final Foo foo = new FooImpl();
proxyFactory.setTarget(foo);
final Foo fooProxy = (Foo) proxyFactory.getProxy();
fooProxy.foo();
fooProxy.baz();
}
}
Encore une fois, si je n'ai que le fichier spring-context.jar dans mon classpath, j'obtiendrai:
An exception occured while executing the Java class. null: InvocationTargetException: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
Lorsque vous étudiez la classe AspectJExpressionPointcutAdvisor, vous constaterez qu'elle étend AbstractGenericPointcutAdvisor et qui délègue le travail à une instance de AspectJExpressionPointcut. Et vous pouvez voir que AspectJExpressionPointcut a les instructions d'importation suivantes:
import org.aspectj.weaver.patterns.NamePattern;
import org.aspectj.weaver.reflect.ReflectionWorld.ReflectionWorldException;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
import org.aspectj.weaver.tools.ContextBasedMatcher;
import org.aspectj.weaver.tools.FuzzyBoolean;
import org.aspectj.weaver.tools.JoinPointMatch;
import org.aspectj.weaver.tools.MatchingContext;
import org.aspectj.weaver.tools.PointcutDesignatorHandler;
import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParameter;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.PointcutPrimitive;
import org.aspectj.weaver.tools.ShadowMatch;
Vous aurez besoin de la dépendance aspectjtools dans votre chemin de classe au moment de l'exécution pour permettre à AspectJExpressionPointcut de charger les classes dont il a besoin.