java


How to handle cyclic dependency in spring


For example i have two beans:
class Bean1 {
private SomeService service1;
private SomeService servive2;
private Bean2 bean2;
public void doStuff() {
service1.doActualStuff();
}
public void setBean2(Bean2 bean2) {
this.bean2 = bean2;
}
public Bean2 getBean2() { return this.bean2 }
}
class Bean2 {
private Bean1 bean1;
private SomeService3 service3;
public void init() {
bean1.doStuff();
}
public void setBean1(Bean1 bean1) {
this.bean1 = bean1;
}
}
Now if i try to configure them in spring in the folllowing way:
<bean id="service1" class="SomeService">
...
</bean>
<bean id="bean1" class="Bean1">
<property name="bean2" ref="bean2"/>
<property name="service1" ref="service1"/>
...
</bean>
<bean id="bean2" class="Bean2" init-method="init">
<property name="bean1" ref="bean1"/>
...
</bean>
Init method of bean2 is executed. Bean2 has injected bean1, but bean1 itself is not fully initialized so calling bean1.doStuff() that will call service1.doActualStuff() will return into NPE. Why bean1 is not fully initialized?
Spring caches singleton beans in a not-fully-initialized state for injection into places that would otherwise be an unresolvable circular reference. In your case, the initialization order would be something like this:
Instantiate bean1 (meaning call the constructor only, not init methods)
Add bean1 to the singleton cache to handle circular dependencies
Start injecting bean1's dependencies
Instantiate bean2 to satisfy bean1's dependency
Add bean2 to the singelton cache to handle circular dependencies
Start injecting bean2's dependencies--one of these is the cached bean1 instance, which is still not fully initialized
Finish injecting bean2's dependencies
Call bean2's init method--uhoh! bean1 still isn't initted yet!
Done creating bean2
(If you actually made it this far...) Finish injecting bean1's dependencies
No init method on bean1, but this is where it would be called
Done creating bean1
Consider rethinking your design to untangle the dependencies between bean1 and bean2.
How about if you inject the first bean programatically:
class Bean2 {
private Bean1 bean1;
private SomeService3 service3;
public void init() {
bean1.doStuff();
}
public void setBean1(Bean1 bean1) {
this.bean1 = bean1;
//HERE
this.bean1.setBean2(this);
}
}
Remove the first injection from your spring xml:
<bean id="service1" class="SomeService">
...
</bean>
<bean id="bean1" class="Bean1">
<!-- NOT NEEDED ANYMORE <property name="bean2" ref="bean2"/> -->
<property name="service1" ref="service1"/>
...
</bean>
<bean id="bean2" class="Bean2" init-method="init">
<property name="bean1" ref="bean1"/>
...
</bean>

Related Links

Java Regex Matching Forward Slash and Word
Spring-boot form post large data taking long to enter filter
Java DataStreams and Sockets
Taking input through console Java
Search through ArrayList for value then copy value & key to new TreeSet
JTable doesn't display data by using click button
Threaded factorial performane in Java
Upgraded from Maven to Gradle, now my webapp returning 404 for main logon page
java.lang.ClassFormatError: JVMCFRE074 no Code attribute specified; class=javax/ejb/RemoveException, method=<init>()V, pc=0
#Transactional Method Calling - should we pass objects as parameters?
HttpURLConnection: Already connected after redirect
How do I change the KeyFrame duration of my timer when user clicks a button?
Java - Reading a line from a file containing text and number
How to interleave Java 8 Stream? Like Collectors.joining() but for things other than Strings
how to limit tests time execution from build xml file
Maven Shade Plugin - NoClassDefFound

Categories

HOME
testing
osgi
netsuite
plone
smarty
stock
lodash
xmpp
at-command
dxl
win32gui
uber-api
portia
slick-slider
cloudkit
iggrid
maude-system
windows-10-universal
facebook-php-sdk
gnupg
u-sql
qt-creator
fortumo
opentracing
foselasticabundle
solaris-10
flux
opencover
orleans
accessor
wijmo
applozic
saas
windows-server-2000
delicious-api
unboundid
lightswitch-2013
microsoft-chart-controls
socialengine
xquery-3.0
hybridauth
android-kernel
fusionpbx
suricata
file-format
xcode-extension
starteam
lumberjack
avro4s
checkboxlist
.net-4.6.2
appcompat
pango
pnotify
python-webbrowser
dotnetzip
rdfs
windows-mobile-6.5
nbconvert
bind9
webdriverjs
crosswalk-runtime
google-feed-api
httplistener
firebaseui
holder.js
bgp
fadeout
bluemix-app-scan
javax.sound.midi
hsv
separator
cartesian-product
sdhc
thredds
emailrelay
drawbitmap
tableau-online
twirl
createprocessasuser
ng-animate
network-interface
elliptic-curve
expected-exception
bundles
mbr
stxxl
prettify
gnu-smalltalk
ivyde
jsctypes
quartz-graphics
enterprisedb
http-unit
kyotocabinet
simba
sublist
gil
nsnetservice
rdoc
google-email-migration
reddot
postgresql-performance
assembly-loading
work-stealing
subscript
zpt
netbeans-7.1
text-coloring
ugc

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App