问题
I wrote an program to trace the performance of an application using AspectJ with a requirement that the tracing can be enabled or disabled at runtime using JMX so that i can change the value using jconsole/HtmlAdaptorServer. Now again i have to keep the Pointcut in AOP.xml file so that we can change the poincut when need. As soon as I am kepping the pointcut in aop .xml file nothing happens.Below is the code please let me know what to do or what am I missing.
Since I am using JMX here I am declaring MBean
package com.ags.performance.asp;
public interface SystemMonitoringAspectMBean {
public void setEnabled(boolean enabled);
public boolean isEnabled();
}
Here I am using MBean and creating an Aspect
package com.ags.performance.asp;
//import ...
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public abstract class AbstractPerformanceMonitoringAspect
implements SystemMonitoringAspectMBean{
private Logger logger = Logger
.getLogger(AbstractPerformanceMonitoringAspect.class);
public volatile boolean enabled ;
@Pointcut
public abstract void monitoredOp();
@Around("monitoredOp()&& !within(AbstractPerformanceMonitoringAspect)")
public Object monitor(ProceedingJoinPoint pjp) throws Throwable {
if (!isEnabled()) {
return pjp.proceed();
}
long start = System.nanoTime();
try {
return pjp.proceed();
} finally {
long complete = System.nanoTime();
logger.log(Level.INFO, "Operation "
+ pjp.getSignature().toShortString() + " took "
+ (complete - start) + " nanoseconds");
}
}
public synchronized void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public synchronized boolean isEnabled() {
return enabled;
}
}
Then I am creating Agent so that I can change the values at runtime
package com.ags.performance.asp;
import com.sun.jdmk.comm.HtmlAdaptorServer;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
@Aspect
public class SystemMonitoringAspect extends AbstractPerformanceMonitoringAspect {
@Pointcut
public void monitoredOp() {
}
public SystemMonitoringAspect(){
MBeanServer mBeanServer = null;
mBeanServer = ManagementFactory.getPlatformMBeanServer();
HtmlAdaptorServer adapter = new HtmlAdaptorServer();
ObjectName adapterName = null;
ObjectName perfAspectBean = null;
try
{
perfAspectBean = new ObjectName( "SystemMonitoringAspect:name=performAspectLogger" );
mBeanServer.registerMBean( this, perfAspectBean );
adapterName = new ObjectName( "SystemMonitoringAspect:name=htmladapter,port=9092" );
adapter.setPort( 9092 );
mBeanServer.registerMBean(adapter, adapterName);
adapter.start();
}
catch( Exception e )
{
e.printStackTrace();
}
}
public static void main(String[] args) {
new SystemMonitoringAspect();
}
}
AOP.xml file which will be kept in META_INF folder
<aspectj>
<aspects>
<!-- aspect name="com.ags.performance.asp.PerformanceLoggingAspect"/-->
<aspect name="com.ags.performance.asp.SystemMonitoringAspect"/>
<concrete-aspect
name="com.ags.performance.asp.SystemMonitoringAspect" extends=
"com.ags.performance.asp.AbstractPerformanceMonitoringAspect">
<pointcut name="monitoredOp" expression="execution(* com.ags..*.*(..)"/>
</concrete-aspect>
</aspects>
<weaver options="-verbose –showWeaveInfo">
</weaver>
</aspectj>
回答1:
Disclaimer: I have never used JMX before, I was just interested in your question and quickly read the beginning of Oracle's JMX Tutorial.
Here is some really simplistic, but fully functional sample code for you. It contains two MBeans:
- the application (just set
active = false
in order to quit the application via JMX) - the interceptor aspect (singleton instantiation model, (just toggle
active = false
oractive = true
as often as you wish in order to change the aspect state via JMX).
Application MBean interface:
package de.scrum_master.app;
public interface ApplicationMBean {
void setActive(boolean active);
boolean isActive();
}
Application:
package de.scrum_master.app;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class Application implements ApplicationMBean {
private boolean active = true;
@Override public void setActive(boolean active) { this.active = active; }
@Override public boolean isActive() { return active; }
private void doSomething() { System.out.println("Application activity"); }
public static void main(String[] args) throws Exception {
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
Application application = new Application();
ObjectName objectName = new ObjectName("de.scrum_master.app:type=Application");
System.out.println("Registering application in JMX");
mBeanServer.registerMBean(application, objectName);
while (application.isActive()) {
application.doSomething();
Thread.sleep(3000);
}
System.out.println("Application was deactivated, exiting");
}
}
Interceptor aspect MBean interface:
package de.scrum_master.aspect;
public interface ActivityInterceptorMBean {
void setActive(boolean active);
boolean isActive();
}
Interceptor aspect:
package de.scrum_master.aspect;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import de.scrum_master.app.Application;
public aspect ActivityInterceptor implements ActivityInterceptorMBean {
private static boolean active = true;
public ActivityInterceptor() throws Exception {
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName objectName = new ObjectName("de.scrum_master.aspect:type=ActivityInterceptor");
System.out.println("Registering activity interceptor aspect in JMX");
mBeanServer.registerMBean(this, objectName);
}
@Override public void setActive(boolean active) {
ActivityInterceptor.active = active;
System.out.println("Interceptor is now " + (active ? "active" : "inactive"));
}
@Override public boolean isActive() { return active; }
before() : if(active) && execution(void Application.doSomething()) {
System.out.println("Intercepted activity: " + thisJoinPointStaticPart);
}
}
Sample output:
Registering application in JMX
Registering activity interceptor aspect in JMX
Intercepted activity: execution(void de.scrum_master.app.Application.doSomething())
Application activity
Intercepted activity: execution(void de.scrum_master.app.Application.doSomething())
Application activity
Intercepted activity: execution(void de.scrum_master.app.Application.doSomething())
Application activity
Interceptor is now inactive
Application activity
Application activity
Application activity
Interceptor is now active
Intercepted activity: execution(void de.scrum_master.app.Application.doSomething())
Application activity
Intercepted activity: execution(void de.scrum_master.app.Application.doSomething())
Application activity
Application was deactivated, exiting
来源:https://stackoverflow.com/questions/24014397/issue-with-aop-and-jmx-without-spring