Hi,
A couple times now, I've run across circular dependency issues where I get
the JRUN servlet error "500 null" on the screen when I call getBean(). In
my case, it is usually because component A depends on B depends on C depends
on A. These circular dependencies can be hard to track down.
I know I can get around this by using setter injection instead of
constructor injection, but my existing code has around 60 service layer
components handled by CS and I find constructor-injection easier to manage.
Are there any recommendations on how to avoid service layer circular
dependencies in general?
I've played around with DefaultXMLBeanFactory.cfc and added an argument to
getBean() and constructBean() to try to detect circular dependencies. I
think it might need to be modded to work with non-singletons. I pasted the
diff below.
Jon
bash-2.05b$ diff DefaultXmlBeanFactory-original.cfc
DefaultXmlBeanFactory.cfc
<cfargument name="beanRetrievalData" required="false" type="struct"
default="#StructNew()#" hint="struct to place information about how we
retrieve the bean"/>
321a323
332c334
< <cfset constructBean(arguments.beanName)/>
---
<cfset
constructBean(arguments.beanName,false,arguments.beanRetrievalData)/>
337c339
< <cfreturn constructBean(arguments.beanName,true)/>
---
<cfreturn
constructBean(arguments.beanName,true,arguments.beanRetrievalData)/>
340c342
< <cfreturn variables.parent.getBean(arguments.beanName)>
---
<cfreturn variables.parent.getBean(arguments.beanName,
arguments.beanRetrievalData)>
355c357
< <cfargument name="returnInstance" type="boolean" required="false"
default="false"
---
<cfargument name="returnInstance" type="boolean" required="true"
356a359
<cfargument name="beanRetrievalData" required="true" type="struct"
hint="struct to place information about how we retrieve the bean"/>
380a384,392
<cfif NOT StructKeyExists(arguments.beanRetrievalData,
"constructedBeans") >
<cfset arguments.beanRetrievalData.constructedBeans = ArrayNew(1)>
</cfif>
<cfif ListFindNoCase(
ArrayToList(arguments.beanRetrievalData.constructedBeans),
arguments.beanName ) >
<cfthrow type="coldspring.CircularDependencyException" detail="Bean:
#arguments.beanName# has already had a request to be constructed. This is
a circular dependency."/>
</cfif>
<cfset ArrayAppend(arguments.beanRetrievalData.constructedBeans,
arguments.beanName) />
527c539
< value="#getBean(argDefs[arg].getValue())#"/> <!---
value="#dependentBeanInstance#" --->
---
value="#getBean(argDefs[arg].getValue(),
arguments.beanRetrievalData)#"/> <!--- value="#dependentBeanInstance#"
--->