我必须为属于com.mycomp的包和子包的所有方法应用日志信息。**。我尝试过在春季参考手册中给出的许多切入点,但遗憾的是没有人为我工作。 我正在使用
@Pointcut("execution(* com.mycomp..(..))")
private void businessService() {} // signature
我得到的是
Caused by: java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting
'name pattern cannot finish with ..' at character position 27
execution(* com.mycomp..(..))
在文档中给出了
@Pointcut("execution( com.xyz.someapp..service..(..))")
我尝试过使用执行(com.mycomp ..(..))但得到了类似的异常。
按照James的建议使用切入点@Around(value =“execution(* xyz.package.foo.bar .. *(..))”)我在启动服务器时遇到了新的异常。
Caused by: java.lang.IllegalStateException: Cannot convert value of type [$Proxy76 implementing org.springframework.context.ApplicationContextAware,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.mycompname.BancsContextAware] for property 'bancsContextAware': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:264)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:448)
... 57 more
后来在调试时发现我在其中一个类中使用了object.getClass()。getAnnotation(),而spring AOP创建的代理对象没有注释。因为只有我得到一个空指针异常。我使用AopProxyUtils.ultimateTargetClass(someObject)对其进行了排序 但现在的问题是我在com.mycom的子包中有一些最终的类和枚举..因为我得到了
nested exception is org.springframework.aop.framework.AopConfigException:
Could not generate CGLIB subclass of class [class com.mycom.util.BancsServiceProvider]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.mycom.util.BancsServiceProvider
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
那么如何从Spring AOP切入点中排除最终类和枚举。
答案 0 :(得分:2)
您正在寻找的切入点和方法是这样的:
@Around(value="execution(* xyz.package.foo.bar..*(..))")
public Object beforeAdvice(ProceedingJoinPoint jp) throws Throwable {
//Get log4j logger for target class.
Logger logger = LogManager.getLogger(jp.getTarget().getClass());
logger.info(jp.getTarget().getClass().getName() + " " + jp.getSignature().getName() + " "
+ "Hit:");
Object returnVal = jp.proceed(jp.getArgs());
logger.info(jp.getTarget().getClass().getName() + " " + jp.getSignature().getName() + " "
+ "Finished:");
return returnVal;
}
上面的代码将在进入方法之前记录类和方法名称以及“命中”,并在以下列方式完成后完成“完成”:
xyz.package.foo.bar.service.getPerson: Hit:
xyz.package.foo.bar.dao.getPerson: Hit:
xyz.package.foo.bar.dao.getPerson: Finished:
xyz.package.foo.bar.service.getPerson: Finished:
...
如果您想尝试遵循方法的多线程执行,只需使用以下内容:
@Around(value="execution(* xyz.package.foo.bar..*(..))")
public Object beforeAdvice(ProceedingJoinPoint jp) throws Throwable {
Logger logger = LogManager.getLogger(jp.getTarget().getClass());
String executionId = UUID.randomUUID().toString();
logger.info(jp.getTarget().getClass().getName() + " " + jp.getSignature().getName() + " "
+ "Hit:" + executionId);
Object returnVal = jp.proceed(jp.getArgs());
logger.info(jp.getTarget().getClass().getName() + " " + jp.getSignature().getName() + " "
+ "Finished:" + executionId);
return returnVal;
}
每个线程调用将获得一个UUID,这将允许您跟踪这些方法在所有线程中执行的速度。我在尝试获取性能测试的方法时间时使用此代码,并且它可以创建奇迹。
确保您将此类声明为一个方面。
答案 1 :(得分:0)
您是否尝试过以下操作?
@Pointcut( “内(com.mycomp .. *)”)