Java 根据环境变量或属性执行切入点

Java 根据环境变量或属性执行切入点,java,eclipse,spring,aspectj,spring-aop,Java,Eclipse,Spring,Aspectj,Spring Aop,我已经开发了一个很好的Spring方面,可以用来监控我的服务操作性能。如果执行某些操作需要很长时间,它会记录这些操作 @Aspect public class PerformanceMonitorAspect { private Logger logger = LoggerFactory.getLogger("performance"); @Pointcut("execution(* com.company.MyService+.*(..))") public voi

我已经开发了一个很好的Spring
方面
,可以用来监控我的服务操作性能。如果执行某些操作需要很长时间,它会记录这些操作

@Aspect
public class PerformanceMonitorAspect {

    private Logger logger = LoggerFactory.getLogger("performance");

    @Pointcut("execution(* com.company.MyService+.*(..))")
    public void pointCut(){

    }

    @Around("pointCut()")
    public Object profileServiceMethods(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        MethodSignature ms = (MethodSignature) thisJoinPoint.getSignature();
        Method m = ms.getMethod();
        long t1 = System.nanoTime();
        Object result = thisJoinPoint.proceed();
        long t2 = System.nanoTime();
        long millis = TimeUnit.NANOSECONDS.toMillis(t2 - t1);
        if (millis < 1000) {
            logger.trace("Execution time for {}: {} ms", m.getName(), millis);
        } else {
            logger.warn("Substantial execution time for {}: {} ms", m.getName(),
                    millis);
        }
        return result;
    }

}
这就是Eclipse不发出任何警告的方式。但是,我在运行时得到以下结果:

GRAVE: Critical error during deployment: 
java.lang.VerifyError: Expecting a stackmap frame at branch target 7
Exception Details:
  Location:
    com/mycompany/aspects/AuditAspect.<clinit>()V @1: invokestatic
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0000000: 00b8 0134 a700 084b 2ab3 012f b1       
  Exception Handler Table:
    bci [1, 7] => handler: 7

    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
    at java.lang.Class.getDeclaredMethods(Class.java:1860)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:474)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:458)
    at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:518)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:639)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:575)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1350)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:355)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:326)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:434)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:624)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:461)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
GRAVE:部署期间出现严重错误:
java.lang.VerifyError:在分支目标7处应为stackmap帧
例外情况详情:
地点:
com/mycompany/aspects/AuditAspect.()V@1:invokestatic
原因:
此位置应为stackmap帧。
字节码:
0000000:00b8 0134 a700 084b 2ab3 012f b1
异常处理程序表:
bci[1,7]=>处理程序:7
位于java.lang.Class.getDeclaredMethods0(本机方法)
位于java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
位于java.lang.Class.getDeclaredMethods(Class.java:1860)
位于org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:474)
位于org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:458)
位于org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:518)
位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:639)
位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:575)
位于org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1350)
位于org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:355)
位于org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:326)
位于org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:434)
位于org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:624)
位于org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:461)
位于org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
位于org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
位于org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
位于org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
位于org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
位于org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
位于org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
位于org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
在java.util.concurrent.FutureTask.run(FutureTask.java:262)处
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
运行(Thread.java:745)
看来织工做得不好。有什么建议吗

编辑2 当我通过SpringAOP基于代理的方面使用AspectJ时,就会出现这个问题。我正在使用Maven构建项目,并使用EclipseApectJ插件将其集成到我的工作区中。AspectJ版本是1.8.2,SpringAOP版本是3.2.8.0版本,我正在用Java7.0.75JDK构建它

以下是所用POM的示例:


4.0.0
com.tesicnor.test
方面测试
0.0.1-快照
罐子
方面测试
http://maven.apache.org
UTF-8
1.7
1.7
1.8.2
org.codehaus.mojo
aspectj maven插件
1.7
1.7
1.7
1.7
编译
org.aspectj
aspectjrt
${aspectj.version}
org.aspectj
aspectjweaver
${aspectj.version}
org.springframework
春季aop
3.2.8.1发布

这个POM是我创建的一个功能测试用例的POM。我当前的项目非常庞大,似乎还有其他依赖项导致了问题。

您可以获得表示当前阶段的属性引用(可能是静态的)。根据它的值,您可以绕过
profileServiceMethods
方法(提前返回)中的代码

以一种不那么美观的方式,您可以在方面中声明一个布尔变量,用于相同的目的:

if(!logActivated)
    return null;
else
    <your code here>

最后,我让它工作了。似乎Eclipse在我的类路径中造成了一些混乱,导致了上述问题。我删除了
aspectjweaver
,根据@DavidL的回答,我可以获得以下代码:

@Aspect
public class PerformanceMonitorAspect {

    /**
     * Decide whether the Pointcut to be executed or not
     */
    private static boolean enabled;

    @Pointcut("execution(* com.company.MyService+.*(..)) && if()")
    public static boolean pointCut() {
        return enabled;
    }

    private Logger logger = LoggerFactory.getLogger("performance");

    @Around("pointCut()")
    public Object profileServiceMethods(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        MethodSignature ms = (MethodSignature) thisJoinPoint.getSignature();
        Method m = ms.getMethod();
        long t1 = System.nanoTime();
        Object result = thisJoinPoint.proceed();
        long t2 = System.nanoTime();
        long millis = TimeUnit.NANOSECONDS.toMillis(t2 - t1);
        if (millis < 1000) {
            logger.trace("Execution time for {}: {} ms", m.getName(), millis);
        } else {
            logger.warn("Substantial execution time for {}: {} ms", m.getName(),
                    millis);
        }
        return result;
    }

    //The value is retrieved by Spring having read a config file written by Maven, depending on the profile
    @Value("${enable.performance.monitor}")
    public void setEnabled(boolean value) {
        enabled = value;
    }

}
@方面
公共类性能监视器方面{
/**
*决定是否执行切入点
*/
启用私有静态布尔值;
@切入点(“执行(*com.company.MyService+.*(..)&&if()”)
公共静态布尔切入点(){
返回启用;
}
私有记录器Logger=LoggerFactory.getLogger(“性能”);
@环绕(“切入点()”)
公共对象配置文件服务方法(ProceedingJoinPoint thisJoinPoint)抛出可丢弃的{
MethodSignature ms=(MethodSignature)thisJoinPoint.getSignature();
方法m=ms.getMethod();
long t1=System.nanoTime();
对象结果
@Pointcut("execution(* com.company.MyService+.*(..)) && args(i) && if()")
public static boolean pointCut(int i) {
    return i == State.PRODUCTION_STAGE ;
}
@Aspect
public class PerformanceMonitorAspect {

    /**
     * Decide whether the Pointcut to be executed or not
     */
    private static boolean enabled;

    @Pointcut("execution(* com.company.MyService+.*(..)) && if()")
    public static boolean pointCut() {
        return enabled;
    }

    private Logger logger = LoggerFactory.getLogger("performance");

    @Around("pointCut()")
    public Object profileServiceMethods(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        MethodSignature ms = (MethodSignature) thisJoinPoint.getSignature();
        Method m = ms.getMethod();
        long t1 = System.nanoTime();
        Object result = thisJoinPoint.proceed();
        long t2 = System.nanoTime();
        long millis = TimeUnit.NANOSECONDS.toMillis(t2 - t1);
        if (millis < 1000) {
            logger.trace("Execution time for {}: {} ms", m.getName(), millis);
        } else {
            logger.warn("Substantial execution time for {}: {} ms", m.getName(),
                    millis);
        }
        return result;
    }

    //The value is retrieved by Spring having read a config file written by Maven, depending on the profile
    @Value("${enable.performance.monitor}")
    public void setEnabled(boolean value) {
        enabled = value;
    }

}
<bean class="com.tadic.aspects.PerformanceMonitorAspect" factory-method="aspectOf" />