We use AOP a lot but due to legacy reasons we dont use aspectJ yet and we are using Spring ProxyFactoryBean and use interceptors to apply AOP behavior like light weight instrumentation or transactions.
Lately we ran into two or three issues where on some proxyFactoryBeans the interceptors wont be applied. My hunch was it was some circular dependency between beans so I added DEBUG on org.springframework.beans in log4j and it spitted tons of logs, I did a grep
grep "that is not fully initialized yet - a consequence of a circular reference" ~/apache-tomcat-7.0.30/logs/ tomcat.log |awk -F "singleton" '{print $2}'|sort|uniq
it would print some message like
Lately we ran into two or three issues where on some proxyFactoryBeans the interceptors wont be applied. My hunch was it was some circular dependency between beans so I added DEBUG on org.springframework.beans in log4j and it spitted tons of logs, I did a grep
grep "that is not fully initialized yet - a consequence of a circular reference" ~/apache-tomcat-7.0.30/logs/
it would print some message like
bean 'gdriveClient' that is not fully initialized yet - a consequence of a circular reference
bean 'gdriveRestServiceHelper' that is not fully initialized yet - a consequence of a circular reference
bean ' filerServiceRequestHandlerFact ory' that is not fully initialized yet - a consequence of a circular reference
bean 'objectReplicationManager' that is not fully initialized yet - a consequence of a circular reference
But this was a painful way to analyse it and I wanted to future proof the code so that developers in future cant introduce a circular dependency.
Today I found that instead of loading context like
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml");
You can do something like
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
context.setAllowCircularReferences(false);
context.setConfigLocation("/applicationContext.xml");
context.refresh();
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
context.setAllowCircularReferences(false);
context.setConfigLocation("/applicationContext.xml");
context.refresh();
and this would fail on first circular reference encountered. This prints in log entire hierarchy of bean it was trying to load so its very easy to chain the beans to find circular reference. I haven’t committed the code yet but the idea is to fix all existing circular dependencies and then enable this code.
Comments
Post a Comment