java - puedo - AOP de primavera-¿Por qué necesito protector de aspecto?
spring boot aop example (5)
Creo que la implementación de Spring AOP está reutilizando algunas clases del aspectj-weaver. Todavía utiliza proxies dinámicos, no hace la modificación del código de bytes.
El siguiente comment del foro de primavera podría aclarar.
La primavera no está utilizando el tejedor AspectJ en este caso. Simplemente está reutilizando algunas de las clases de aspectjweaver.jar.
-Ramnivas
Escribí un Aspecto muy simple con Spring AOP. Funciona, pero tengo algunos problemas para entender lo que realmente está sucediendo. No entiendo por qué tengo que agregar el aspectjweaver.jar? La documentación de Spring-AOP indica claramente que no necesito un compilador o tejedora de aspectj siempre que solo use Spring-AOP:
Sin embargo, el tiempo de ejecución de AOP sigue siendo puro AOP de primavera, y no hay dependencia en el compilador o tejedor de AspectJ.
Mi configuración se ve así:
<aop:aspectj-autoproxy />
@Aspect
@Service
public class RemoteInvocationAspect {
@Before("execution(* at.test.mypackage.*.*(..))")
public void test() {
System.out.println("test");
}
...
También probé la configuración XML, aunque no cambié nada. Tal vez podría dejarlo ir, pero realmente me gustaría entender por qué se usa aspectj-weaver? Si no agrego la dependencia en maven obtengo java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
Estás usando el estilo AspectJ pointcut-expression @Aspect
y @Before
son parte de AspectJ. Mira este enlace
En lo que respecta al AspectJ-weaver
, en realidad es un código de bytes que teje aspectos en clases en el momento de carga .
Hace poco tuve una pregunta similar. ¿Por qué Spring lanza un error de aspectj si no depende de aspectj?
Para usar Spring AoP sin una dependencia de AspectJ, se debe hacer en xml. Las anotaciones son parte de AspectJ.
Además, el lenguaje de expresión realmente genial solo es compatible con AspectJ. Por lo tanto, debe definir cortes de puntos explícitos. Vea la Sección 6.3.2. Declaración de un punto de corte: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html sección
Todavía tengo problemas para encontrar documentación elaborada sobre esta técnica.
Necesita las dependencias aspectjtools o aspectjweaver cuando usa el lenguaje de expresión pointcut de AspectJ.
Por favor vea las siguientes clases:
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!");
}
}
Y por favor vea la versión de 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();
}
}
La salida de la ejecución de este ejemplo será:
Bar!
Foo!
Baz!
Solo necesito org.springframework: spring-context.jar en mi classpath. Ahora, en lugar de NameMatchMethodPointcutAdvisor, usemos 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();
}
}
Nuevamente, si solo tengo el archivo spring-context.jar en mi classpath, obtendré:
An exception occured while executing the Java class. null: InvocationTargetException: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
Cuando investigue la clase AspectJExpressionPointcutAdvisor , verá que extiende AbstractGenericPointcutAdvisor y que delega el trabajo a una instancia de AspectJExpressionPointcut . Y puede ver que AspectJExpressionPointcutcut tiene las siguientes declaraciones de importación:
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;
Necesitará la dependencia de aspectjtools en su ruta de clase en tiempo de ejecución para que AspectJExpressionPointcutcut pueda cargar las clases que necesita.
Puede navegar por el sitio web de Spring y encontrar la respuesta en la página de docs.spring.io
El soporte de @AspectJ puede habilitarse con configuración de estilo XML o Java. En cualquier caso, también deberá asegurarse de que la biblioteca aspectjweaver.jar de AspectJ esté en la ruta de clase de su aplicación (versión 1.6.8 o posterior). Esta biblioteca está disponible en el directorio ''lib'' de una distribución AspectJ o a través del repositorio de Maven Central.