JBoss development,
A new message was posted in the thread "Optimizing aop lifecycle":
http://community.jboss.org/message/518307#518307
Author : Kabir Khan
Profile :
http://community.jboss.org/people/kabir.khan@jboss.com
Message:
--------------------------------------------------------------
My original plan was to just hard-code the annotation plugins on startup, but I then
realised that we probably still want to be able to deploy them. So, when this is parsed:
<lifecycle-configure
name="LifecycleCallback"
class="org.jboss.test.microcontainer.support.LifecycleCallbackWithBeanDependency"
classes="(a)org.jboss.test.microcontainer.support.Lifecycle">
</lifecycle-configure>
A bean called LifecycleCallback implemented by LCWDB is installed (as before), and an
instance of LifecycleAnnotationPlugin handling @Lifecycle is added by the LifecycleBinding
bean.
Previously instead of LAPlugin the LifecycleBinding bean installed a lifecycle pointcut to
the AspectManager, and pointcut matching was done as part of AOPDependencyBuilder using
the info from the AspectManager. AOPDepBuilder would create a
LifecycleAspectDependencyBuilderListItem which would set up the correct dependencies and
set up the lifecycle callback items in the matching context's dependency info.
Lifecycle calbacks would then be invoked by
AbstractController.handleLifecycleCallbacks().
Now instead of the AOPDepBuilder doing fancy and heavy pointcut matching to determine
lifecycle callbacks, the LifecycleAnnotationPlugin is invoked as part of
DescibeAction.applyAnnotations() -> BeanAnnotationAdapter.applyAnnotations().
If we deploy a bean that has the @Lifecycle annotation BAA picks that up and it is handled
by LifecycleAnnotationAdapter which uses LifecycleAspectDependencyBuilderListItem to set
up the dependencies and dependency info as before. I just used LADBLI since the code was
already there, but am planning to refactor that somehow
Anyway, the question I really had was: am I ok to expose the add/removeAnnotationPlugin()
methods in the BeanAnnotationAdapter interface?
Code from LifecycleBinding:
public void start() throws Exception
{
.....
if (!classes.startsWith("@"))
throw new IllegalArgumentException("Could not parse '" + classes +
" into an annotation. (It must start with '@')");
String annotationName = classes.substring(1);
Class<Annotation> clazz = null;
try
{
clazz =
(Class<Annotation>)SecurityActions.getContextClassLoader().loadClass(annotationName);
}
catch (Exception e)
{
throw new IllegalArgumentException("An error occurred loading '" +
classes + "'", e);
}
LifecycleAspectDependencyBuilderListItem item = new
LifecycleAspectDependencyBuilderListItem(callbackBean, state, installMethod,
uninstallMethod);
plugin = new LifecycleAnnotationPlugin<Annotation>(clazz, item);
getBeanAnnotationAdapter().addAnnotationPlugin(plugin);
}
public void stop() throws Exception
{
if (plugin != null)
getBeanAnnotationAdapter().removeAnnotationPlugin(plugin);
}
@SuppressWarnings("unchecked")
private CommonAnnotationAdapter<AnnotationPlugin<?, ?>, MetaDataVisitor>
getBeanAnnotationAdapter()
{
BeanAnnotationAdapter adapter =
BeanAnnotationAdapterFactory.getInstance().getBeanAnnotationAdapter();
if (adapter instanceof CommonAnnotationAdapter == false)
throw new IllegalArgumentException("Adapter is not an instance of
CommonAnnotationAdapter");
return (CommonAnnotationAdapter<AnnotationPlugin<?,?>,
MetaDataVisitor>)adapter;
}
public class LifecycleAnnotationPlugin<C extends Annotation> extends
ClassAnnotationPlugin<C> implements CleanablePlugin
{
Logger log = Logger.getLogger(LifecycleAnnotationPlugin.class);
private final DependencyBuilderListItem item;
private final Set<KernelControllerContext> handledContexts = new
ConcurrentSet<KernelControllerContext>();
public LifecycleAnnotationPlugin(Class<C> annotation, DependencyBuilderListItem
item)
{
super(annotation);
if (item == null)
throw new IllegalArgumentException("Null dependency builder list
item");
this.item = item;
}
@Override
protected List<? extends MetaDataVisitorNode> internalApplyAnnotation(ClassInfo
info, MetaData retrieval, C annotation, KernelControllerContext context) throws Throwable
{
item.addDependency(context);
handledContexts.add(context);
return null;
}
@Override
protected void internalCleanAnnotation(ClassInfo info, MetaData retrieval, C
annotation, KernelControllerContext context) throws Throwable
{
item.removeDependency(context);
handledContexts.remove(context);
}
public void clean()
{
for (KernelControllerContext context : handledContexts)
{
try
{
internalCleanAnnotation(null, null, null, context);
}
catch(Throwable t)
{
log.warn("An error occurred cleaning " + context, t);
}
}
}
}
The clean() method is called by CommonBeanAnnotationAdapter.removeAnnotationPlugin() to
make sure that we remove the dependency from the contexts affected by the annotation.
--------------------------------------------------------------
To reply to this message visit the message page:
http://community.jboss.org/message/518307#518307