Spring AOP - why do i need aspectjweaver?

35,903

Solution 1

Spring AOP implementation I think is reusing some classes from the aspectj-weaver. It still uses dynamic proxies - doesn't do byte code modification.

The following comment from the spring forum might clarify.

Spring isn't using the AspectJ weaver in this case. It is simply reusing some of the classes from aspectjweaver.jar.

-Ramnivas

Solution 2

You are using AspectJ style pointcut-expression @Aspect and @Before are part of AspectJ. Check this link.

Regarding the AspectJ-weaver, its actually a bytecode weaver which weaves aspects into classes at load time.

Solution 3

I recently had a similar question Why does spring throw an aspectj error if it does not depend on aspectj?

To use Spring AoP without an AspectJ dependency it must be done in xml. The annotations are a part of AspectJ.

Also, the really cool expression language is only supported by AspectJ. So you have to define explicit point-cuts. See Section 6.3.2. Declaring a pointcut: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html section

I'm still having trouble finding any elaborate documentation on this technique.

Solution 4

You need the aspectjtools or the aspectjweaver dependencies when you use the AspectJ pointcut expression language.

Please see the following classes:

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!");
    }
}

And please see 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();
    }
}

The output of running this example will be:

Bar!
Foo!
Baz!

I only need the org.springframework:spring-context.jar in my classpath. Now instead of a NameMatchMethodPointcutAdvisor, lets use 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();
    }
}

Again, if I only have the spring-context.jar in my classpath, I will get:

An exception occured while executing the Java class. null: InvocationTargetException: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException

When you investigate the AspectJExpressionPointcutAdvisor class, you will see that it extends AbstractGenericPointcutAdvisor and which delegates the work to an instance of AspectJExpressionPointcut. And you can see that AspectJExpressionPointcut has the following import statements:

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;

You will need the aspectjtools dependency in your classpath in runtime so AspectJExpressionPointcut can load the classes it needs.

Share:
35,903
Mario B
Author by

Mario B

Updated on November 02, 2020

Comments

  • Mario B
    Mario B over 3 years

    i wrote a very simple Aspect with Spring AOP. It works, but i have some problems understanding what is really going on. I don't understand why i have to add the aspectjweaver.jar? The Spring-AOP documentation clearly states that i don't need aspectj compiler or weaver as long as i just use Spring-AOP:

    The AOP runtime is still pure Spring AOP though, and there is no dependency on the AspectJ compiler or weaver.

    My configuration looks like this:

    <aop:aspectj-autoproxy />
    
    @Aspect
    @Service
    public class RemoteInvocationAspect {
    
        @Before("execution(* at.test.mypackage.*.*(..))")
        public void test() {
            System.out.println("test");
        }
        ...
    

    I also tried XML configuration, didn't change anything though. Maybe i could just let it go, but i really would like to understand why aspectj-weaver is used? If i don't add the dependency in maven i get java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException

  • Mario B
    Mario B almost 12 years
    I understand that. Still, regarding to the documentation i should be able to use AspectJ style pointcuts without using aspectj-weaver.
  • Santosh
    Santosh almost 12 years
    As people have pointed out here, spring is reusing some of classes from AspectJ. Those classes might require AspectJ specific bytecode weaving and hence aspectj-weaver.
  • Koray Tugay
    Koray Tugay over 6 years
    This does not answer the question.