请...有人能解释一下使用以下弹簧切入点指示符之间有什么区别吗?
使用"切入点指示符":
<aop:pointcut expression="within(my.app.dao.impl.*)" id="commonDaoOperation"/>
Run Code Online (Sandbox Code Playgroud)
使用"执行切入点指示符":
<aop:pointcut expression="execution(public * my.app.dao.impl.*.*(..))" id="commonDaoOperation"/>
Run Code Online (Sandbox Code Playgroud)
我在我的web项目中使用第二个(我认为它是最常用的),我用这种方法发现的问题是它在堆中消耗了大量内存......
在使用"eclipse内存分析器"分析应用程序服务器的"堆转储"后,我发现我的应用程序消耗了450 MB,并且该类的实例"org.springframework.aop.aspectj.AspectJExpressionPointcut"正在消耗这些450 MB的30%......
每个实例AspectJExpressionPointcut占用6 MB(大约),这是因为每个实例都保留了与java.lang.reflect.Method实例匹配的缓存,并且令人惊讶的是有很多java方法被缓存(我的切入点表达式没有提到的方法).
在阅读Spring Documentation之后,我决定使用第一种方法(在切入点指示符内),现在每个实例AspectJExpressionPointcut占用的内存都少得多.
问题是关于......他们之间的表现有什么不同......
提前谢谢了...
我必须检测字段值的变化.我想将之前的值与新值进行比较.我不知道字段名称或类型.(更多背景信息.)对于给定类的示例:
package eu.zacheusz.aspectjtries;
@eu.zacheusz.aspectjtries.MyAnnotation
public class Sample {
private String field;
public void modify(){
this.field = "new";
}
public static void main(String[] a){
new Sample().modify();
}
}
Run Code Online (Sandbox Code Playgroud)
我有这个方面:
package eu.zacheusz.aspectjtries.aspects;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class SampleAspect {
@After(" set(!static !final !transient * (@eu.zacheusz.aspectjtries.MyAnnotation *) . *) && args(value) && target(m) ")
public void afterSetField(Object m, Object value){
System.out.println("After set field. value=" + value + " target=" + m.getClass());
}
}
Run Code Online (Sandbox Code Playgroud)
线程"main"中的异常org.springframework.beans.factory.BeanCreationException:创建名为'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0'的bean时出错:bean的实例化失败; 嵌套异常是org.springframework.beans.BeanInstantiationException:无法实例化bean类[org.springframework.aop.aspectj.AspectJPointcutAdvisor]:构造函数抛出异常; 嵌套异常是java.lang.IllegalArgumentException:切入点格式不正确:期望在名称位置49执行'name pattern'(*com.idol.performers.Performer.perform(..)
我的切入点有什么问题?在书中它说
(..) // means taking any arguments
Run Code Online (Sandbox Code Playgroud)
我的xml:
...
<aop:before pointcut="execution(*com.idol.performers.Performer.perform(..))" method="takeSeats"/>
...
Run Code Online (Sandbox Code Playgroud) 任何人都可以解释aspectj this()和target()pointjuts 之间的区别.我尝试在其他地方找到这个,但似乎没有一个明确的答案.谢谢
我有一个名为@Invisible的自定义Annotation.现在我想匹配所有调用一个没有@Invisible Annotation的方法.我怎样才能做到这一点?(带注释样式开发)
我的第一次尝试是:
@Pointcut("execution(!@my.package.Invisible * some.other.package.execute(..))")
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用......
换句话说:如果方法具有Invisible注释,我想忽略它.否则我想用我的建议执行一些代码......
我想在Spring(3.2.3)@Controller中的每个方法之前运行一些代码.我有以下定义,但它不会运行.我怀疑切入点表达式是不正确的.
调度员servlet.xml中
<aop:aspectj-autoproxy/>
<bean class="com.example.web.controllers.ThingAspect"/>
Run Code Online (Sandbox Code Playgroud)
cewcThingAspect
@Pointcut("execution(com.example.web.controllers.ThingController.*(..))")
public void thing() {
}
@Before("thing()")
public void doStuffBeforeThing(JoinPoint joinPoint) {
// do stuff here
}
Run Code Online (Sandbox Code Playgroud) 我得到以下建议: -
@Before(value="@annotation(loggable)", argNames="joinPoint, loggable")
public void before(JoinPoint joinPoint, Loggable loggable) {
Class<? extends Object> clazz = joinPoint.getTarget().getClass();
MethodSignature methodSignature = (MethodSignature) joinPoint
.getSignature();
Method method = methodSignature.getMethod();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
RequestMapping myAnnotation = method
.getAnnotation(RequestMapping.class);
CodeSignature codeSignature = (CodeSignature) joinPoint
.getSignature();
String[] argNames = codeSignature.getParameterNames();
logger.info(".....");
}
Run Code Online (Sandbox Code Playgroud)
在类LoggerAspect中:
package net.prcins.esales.web.aspects;
import java.lang.reflect.Method;
import net.prcins.esales.aspect.IRequestLogger;
import net.prcins.esales.log.annotation.Loggable;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.CodeSignature;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; …Run Code Online (Sandbox Code Playgroud) 在我们的应用程序中,我们有几个(实际上很多,大约30个)Web服务.每个Web服务都驻留在自己的WAR文件中,并且具有自己的Spring上下文,该上下文在应用程序启动时初始化.
我们还有许多应用于Web服务类的注释驱动的方面类.在开始时,poincut表达式看起来像这样:
@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..))")
public void methodsToBeLogged() {
}
Run Code Online (Sandbox Code Playgroud)
并且通过配置输入启用了AOP服务.
但是当网络服务的数量增加时,我们开始OutOfMemoryException在服务器上体验s.在进行一些分析和分析之后,看起来内存是由AspectJExpressionPointcut类的实例保存的缓存占用的.
每个实例的缓存大约是5 MB.由于我们有3个方面和30个服务,因此共有90个实例共存储了450MB的数据.
在检查了缓存的内容后,我们意识到它包含了WAR中存在的所有类的Java反射方法实例,即使是那些不属于my.package.service.business包的类.修改了切点表达式后还有附加within条款:
@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..)) &&
within(my.package.service.business..*)")
public void methodsToBeLogged() {
}
Run Code Online (Sandbox Code Playgroud)
内存使用量再次降至正常水平.并且所有AspectJExpressionPointcut实例总共花费不到1MB.
有人可以解释为什么会这样吗?为什么第一点切割表达还不够?为什么AspectJExpressionPointcut不共享缓存?
为此做一个简洁的标题很难.
无论如何,想象一下我有一个父类:
public class Shape {
public Dimensions getDimensions() {
// Does some generic stuff.
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个派生类来覆盖getDimensions方法:
public class Circle extends Shape {
public Dimensions getDimensions() {
// Does some stuff.
super.getDimensions();
}
}
Run Code Online (Sandbox Code Playgroud)
当我创建一个带有切入点的方面时Shape.getDimensions,切入点Circle.getDimensions被调用两次:一次用于Circle.getDimensions,然后一次调用super.getDimensions.
切入点看起来像这样: @Pointcut("execution(* Shape.getDimensions(..))")
我在建议中添加了一个黑客来检查声明类型的名称(使用JoinPoint.getSignature().getDeclaringType().getName()),但我发现它相当粗糙,感觉有点像黑客.我认为必须有一个更好的方法来做到这一点.
在那儿?
如果格式不是很好,请道歉.第一次在这里问一个问题(我通常可以找到答案).
我一直在使用AspectJ,它在包含注释的对象范围字段上运行良好.我刚刚遇到一种情况,我想要注释一个方法范围的变量,它将与我的切入点一起工作,但我遇到了麻烦.
这是我正在使用的切入点.如果我的变量是对象的字段,它工作正常,但如果我将范围缩小到方法(在方法内声明的变量),那么它不再工作,我不知道为什么.让我知道我能做些什么,谢谢.
after(final Trigger trigger): set(@Triggereable * *) && args(trigger)
{
System.out.println("trigger flush");
}
Run Code Online (Sandbox Code Playgroud)
此外,这是我想要工作的例子.在实例化Trigger时,应触发上面的System.out.println:
public void foo()
{
@Triggereable
private Trigger trigger = new Trigger();
}
Run Code Online (Sandbox Code Playgroud) pointcut ×10
java ×8
aspectj ×7
spring ×4
spring-aop ×4
aop ×3
annotations ×1
aspect ×1
expression ×1
methods ×1
pointcuts ×1
spring-mvc ×1
super ×1
variables ×1