我写了Spring AOP的一个非常简单的看点。 它的工作原理,但我有一些问题了解什么是真正回事。 我不明白为什么我要补充的aspectjweaver.jar? 弹簧AOP文档中明确指出,我不需要AspectJ编译器或编织器,只要我只是用Spring的AOP:
,AOP在运行时仍旧是纯的Spring AOP,并且对AspectJ编译器或编织器没有依赖性。
我的配置是这样的:
<aop:aspectj-autoproxy />
@Aspect
@Service
public class RemoteInvocationAspect {
@Before("execution(* at.test.mypackage.*.*(..))")
public void test() {
System.out.println("test");
}
...
我也试过XML配置,虽然没有任何改变。 也许我只是让他走,但我真的想明白为什么,AspectJ织入使用? 如果我不加在行家依赖我得到java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
Spring AOP的实现,我认为是重用从AspectJ的织入一些类。 它仍然使用动态代理 - 不执行字节码的修改。
下面的评论从春季论坛会澄清。
春天不使用在这种情况下AspectJ织入。 这只不过是重复使用一些类从aspectjweaver.jar。
-Ramnivas
您正在使用的AspectJ风格的切入点表达@Aspect
和@Before
是AspectJ的一部分。 检查此链接 。
关于AspectJ-weaver
,其实际上是一个字节码织入其在加载时间编织方面为类 。
我最近有一个类似的问题, 为什么春天抛出AspectJ的错误,如果它不依赖于AspectJ的?
要使用Spring AOP中没有AspectJ的依赖,必须在XML来完成。 注解是AspectJ中的一部分。
此外,非常酷的表达式语言只由AspectJ的支持。 所以,你必须定义明确的点式切口。 请参见6.3.2节。 声明一个切入点: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html节
我仍然无法找到这种技术的任何复杂的文档。
您可以浏览春的网站,找到的网页上的答复docs.spring.io
@AspectJ支持后可以用XML或Java风格配置中启用。 在这两种情况下,你还需要确保AspectJ的aspectjweaver.jar库是您的应用程序(1.6.8或更高版本)的类路径。 这个库可以在AspectJ的分布“lib”目录下或通过Maven的中央仓库可用。
当您使用AspectJ切入点表达式语言,你需要aspectjtools或aspectjweaver依赖。
请看下面的类:
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!");
}
}
并请参阅App.java版本- 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();
}
}
运行这个例子的输出将是:
Bar!
Foo!
Baz!
我只需要org.springframework:弹簧context.jar在我的类路径中。 现在不是一个NameMatchMethodPointcutAdvisor,让使用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();
}
}
再次,如果我只有在我的类路径弹簧context.jar,我会得到:
An exception occured while executing the Java class. null: InvocationTargetException: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
当你调查AspectJExpressionPointcutAdvisor类,你会看到,它扩展AbstractGenericPointcutAdvisor和代表工作,AspectJExpressionPointcut的一个实例。 你可以看到,AspectJExpressionPointcut有以下import语句:
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;
您需要在运行时类路径中aspectjtools依赖性,因此AspectJExpressionPointcut可以加载它需要的类。