From: <bil...@jb...> - 2005-07-07 00:32:22
|
Kabir, This is to Kabir, but anybody else is welcome to contribute to the discussion. For AOP 2.0 I want to rearchitect our code instrumentation to support a variety of things. This should be an iterative process so that we can meet various deadlines for the microcontainer. Iteration 1: * Should be able to define different advice chains for inherited methods. http://jira.jboss.com/jira/browse/JBAOP-154 * Should be able to define different class metadata/annotation overrides for inherited methods. http://jira.jboss.com/jira/browse/JBAOP-155 * Make the instrumentor pluggable so we can have a heavily (risky) optimized version of instrumentation. * Please rename MethodInfo to MethodJoinpoint or something like that. Also create Constructor and Field structurs that hold the same information as MethodInfo's as we will eventually want to pass these structures in as parameters when we implement before/after throwing, etc... * Per method, field, call by chains on a per instance basis. InstanceAdvisor API is too limited. We should be able to attach AdviceBindings on a per instance and on a per ClassAdvisor basis. The idea is that we generate a classadvisor class at instrumentation time that is specific for the class it is advising. This class has a org.jboss.aop.Domain member variable. A Domain as the same interface as an AspectManager. Except, when you add/remove from the Domain, you will be recalculating the interceptor stacks. The InstanceAdvisor is also a generated class. It extends the ClassAdvisor generated class. It also has its own Domain that is a child of the generated ClassAdvisor's domain. The InstanceAdvisor is different than the ClassAdvisor in that it must check to see if the ClassAdvisor's interceptor stacks have changed (hot deployment) and recalculate its own internal interceptor stacks. So, the InstanceAdvisor's Domain is a child of the ClassAdvisor's, the ClassAdvisor's domain is a child of the AspectManager.instance(). You have full freedom to refactor, rewrite, or throw out any code you want. Here's example code for ideas. | public class POJO | { | private static Advisor classAdvisor = new POJOAdvisor(); | protected volatile Advisor currentAdvisor = getClassAdvisor(); | protected Advisor instanceAdvisor = null; | | public Advisor getClassAdvisor() | { | return classAdvisor; | } | | public boolean isInstanceAdvised() | { | return instanceAdvisor != null; | } | | public Advisor getInstanceAdvisor() | { | synchronized(this) | { | if (instanceAdvisor == null) | { | instanceAdvisor = ((POJOAdvisor)currentAdvisor).createInstanceAdvisor(); | currentAdvisor = instanceAdvisor; | } | } | return instanceAdvisor; | } | | private int method1(int arg) | { | return ((POJOAdvisor)currentAdvisor).method1(this, arg); | } | | private int method1$aop(int arg) | { | return 0; | } | | private static int methodstatic() | { | return ((POJOAdvisor)classAdvisor).methodstatic(); | } | | private static int methodstatic$aop() | { | return 0; | } | | protected static class POJOAdvisor extends Advisor | { | protected long versionId = 0; | protected Domain domain = new Domain(AspectManager.instance(), false); | | public POJOAdvisor() | { | // create interceptor stack based on domain member variable. | } | | public Domain getDomain() | { | return domain; | } | | public POJOAdvisor createInstanceAdvisor() | { | return new POJOInstanceAdvisor(this); | } | | protected MethodInfo method1$MethodInfo = new MethodInfo(/*other stuff */); | protected int method1(POJO target, int arg) | { | if (method1$MethodInfo.interceptors != null) | { | MethodInvocation invocation = new MethodInvocation(method1$MethodInfo, method1$MethodInfo.interceptors); // put in the correct constructor | invocation.setTargetObject(target); | invocation.setArguments(...); | return ((Integer)invocation.invokeNext()).intValue(); | } | else | { | return target.method1$aop(arg); | } | } | | private MethodInfo methodstatic$MethodInfo = new MethodInfo(/*other stuff */); | private int methodstatic() | { | if (methodstatic$MethodInfo.interceptors != null) | { | MethodInvocation invocation = new MethodInvocation(methodstatic$MethodInfo, methodstatic$MethodInfo.interceptors); // put in the correct constructor | return ((Integer)invocation.invokeNext()).intValue(); | } | else | { | return methodstatic$aop(); | } | } | } | | protected static class POJOInstanceAdvisor extends POJOAdvisor | { | protected POJOAdvisor classAdvisor; | | public POJOInstanceAdvisor(POJOAdvisor classAdvisor) | { | this.classAdvisor = classAdvisor; | this.versionId = classAdvisor.versionId; | } | | protected int method1(POJO target, int arg) | { | if (versionId != classAdvisor.versionId) | { | versionId = classAdvisor.versionId; | rebuildInterceptors(); | } | return super.method1(target, arg); | } | } | | } | | | public class POJOChild extends POJO | { | private static Advisor classAdvisor = new POJOChildAdvisor(AspectManager.instance()); | | public Advisor getClassAdvisor() | { | return classAdvisor; | } | | public void method2() | { | ((POJOChildAdvisor)currentAdvisor).method2(this); | } | | public void method2$aop() | { | // actual code | } | | protected static class POJOChildAdvisor extends POJO.POJOAdvisor | { | protected MethodInfo method1$MethodInfo = new MethodInfo(/*other stuff */); | protected void method2(POJOChild target) | { | if (method1$MethodInfo.interceptors != null) | { | MethodInvocation invocation = new MethodInvocation(method1$MethodInfo, method1$MethodInfo.interceptors); // put in the correct constructor | invocation.setTargetObject(target); | invocation.invokeNext(); | } | else | { | target.method2$aop(); | } | } | | public POJOAdvisor createInstanceAdvisor() | { | return new POJOChildInstanceAdvisor(this); | } | | } | } | View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3883934#3883934 Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=3883934 |