SPR-6885
Improved documentation for JavaConfig's use of CGLIB for all @Configuration annotated classes
This commit is contained in:
parent
9e71af86f8
commit
6af91773ee
|
@ -6658,6 +6658,9 @@ public class AppConfig {
|
||||||
} </programlisting></para>
|
} </programlisting></para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<section id="beans-java-bean-aliasing">
|
<section id="beans-java-bean-aliasing">
|
||||||
<title>Bean aliasing</title>
|
<title>Bean aliasing</title>
|
||||||
|
|
||||||
|
@ -6677,6 +6680,66 @@ public class AppConfig {
|
||||||
} </programlisting></para>
|
} </programlisting></para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section id="further-information-java-bean-annotation">
|
||||||
|
<title>Further information about how Java-based configuration works internally</title>
|
||||||
|
|
||||||
|
<para>The following example shows a <literal>@Bean</literal> annotated method being called twice:</para>
|
||||||
|
|
||||||
|
<programlisting language="java">
|
||||||
|
@Configuration
|
||||||
|
public class AppConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientService clientService1() {
|
||||||
|
ClientServiceImpl clientService = new ClientServiceImpl();
|
||||||
|
clientService.setClientDao(clientDao());
|
||||||
|
return clientService;
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientService clientService2() {
|
||||||
|
ClientServiceImpl clientService = new ClientServiceImpl();
|
||||||
|
clientService.setClientDao(clientDao());
|
||||||
|
return clientService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientDao clientDao() {
|
||||||
|
return new ClientDaoImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
<methodname>clientDao()</methodname> has been called once in <methodname>clientService1()</methodname> and once in
|
||||||
|
<methodname>clientService2()</methodname>.
|
||||||
|
Since this method creates a new instance of <classname>ClientDaoImpl</classname> and returns it, you would normally expect having 2 instances
|
||||||
|
(one for each service).
|
||||||
|
That definitely would be problematic: in Spring, instantiated beans have a <literal>singleton</literal> scope by default.
|
||||||
|
This is where the magic comes in:
|
||||||
|
All <literal>@Configuration</literal> classes are subclassed at startup-time with <literal>CGLIB</literal>. In the subclass, the child method checks the container first for any
|
||||||
|
cached (scoped) beans before it calls the parent method and creates a new instance.
|
||||||
|
</para>
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
Behaviour could be different according to the scope
|
||||||
|
of your bean. We are talking here about Singletons.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
There are a few restrictions due to the use of CGLIB to dynamically add features startup-time:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Configuration classes should not be final</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>They should have a constructor with no arguments</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="context-load-time-weaver">
|
<section id="context-load-time-weaver">
|
||||||
|
|
Loading…
Reference in New Issue