From 84a3cb868a1966ea1f4b482b3892ac16b1ee62e4 Mon Sep 17 00:00:00 2001 From: Thomas Risberg Date: Wed, 29 Apr 2009 21:14:01 +0000 Subject: [PATCH] added some JavaConfig content git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@1076 50f2f4bb-b051-0410-bef5-90022cba6387 --- spring-framework-reference/src/beans.xml | 947 ++++++++++++------ .../src/spring-framework-reference.xml | 14 +- 2 files changed, 642 insertions(+), 319 deletions(-) diff --git a/spring-framework-reference/src/beans.xml b/spring-framework-reference/src/beans.xml index 3716d9ccbf2..fd56f196199 100644 --- a/spring-framework-reference/src/beans.xml +++ b/spring-framework-reference/src/beans.xml @@ -1,5 +1,5 @@ - The IoC container @@ -205,23 +205,23 @@ Find below an example of the basic structure of XML-based configuration metadata. - <?xml version="1.0" encoding="UTF-8"?> -<beans xmlns="http://www.springframework.org/schema/beans" + + - <bean id="..." class="..."> - <!-- collaborators and configuration for this bean go here --> - </bean> + + + - <bean id="..." class="..."> - <!-- collaborators and configuration for this bean go here --> - </bean> + + + - <!-- more bean definitions go here --> + -</beans> +]]> @@ -254,16 +254,16 @@ BeanFactory factory = context; load bean definitions from another file (or files). Let's look at a sample: - <beans> + - <import resource="services.xml"/> - <import resource="resources/messageSource.xml"/> - <import resource="/resources/themeSource.xml"/> + + + - <bean id="bean1" class="..."/> - <bean id="bean2" class="..."/> + + -</beans> +]]> In this example, external bean definitions are being loaded from 3 files, services.xml, @@ -518,7 +518,7 @@ BeanFactory factory = context; XML-based configuration metadata this may be accomplished via the use of the <alias/> element. - <alias name="fromName" alias="toName"/> + ]]> In this case, a bean in the same container which is named 'fromName', may also after the use of this alias @@ -534,8 +534,8 @@ BeanFactory factory = context; easily handled by adding to the MyApp XML fragment the following standalone aliases: - <alias name="componentA-dataSource" alias="componentB-dataSource"/> -<alias name="componentA-dataSource" alias="myApp-dataSource" /> + +]]> Now each component and the main application can refer to the dataSource via a name that is unique and guaranteed not to clash @@ -622,9 +622,9 @@ BeanFactory factory = context; When using XML-based configuration metadata you can specify your bean class like so: - <bean id="exampleBean" class="examples.ExampleBean"/> + -<bean name="anotherExample" class="examples.ExampleBeanTwo"/> +]]> The mechanism for supplying arguments to the constructor (if required), or setting properties of the object instance after it has @@ -654,9 +654,9 @@ BeanFactory factory = context; this example, the createInstance() method must be a static method. - <bean id="exampleBean" + + factory-method="createInstance"/>]]> The mechanism for supplying (optional) arguments to the factory method, or setting properties of the object instance after @@ -724,8 +724,8 @@ BeanFactory factory = context; BeanFactory you would create one and read in some bean definitions in the XML format as follows: - Resource res = new FileSystemResource("beans.xml"); -BeanFactory factory = new XmlBeanFactory(res); + Basically that is all there is to it. Using getBean(String) you can retrieve instances of @@ -830,16 +830,16 @@ public class Foo { specify the constructor argument indexes and / or types explicitly. - <beans> - <bean name="foo" class="x.y.Foo"> - <constructor-arg> - <bean class="x.y.Bar"/> - </constructor-arg> - <constructor-arg> - <bean class="x.y.Baz"/> - </constructor-arg> - </bean> -</beans> + + + + + + + + + +]]> When another bean is referenced, the type is known, and matching can occur (as was the case with the preceding example). @@ -872,10 +872,10 @@ public class ExampleBean { the constructor argument using the 'type' attribute. For example: - <bean id="exampleBean" class="examples.ExampleBean"> - <constructor-arg type="int" value="7500000"/> - <constructor-arg type="java.lang.String" value="42"/> -</bean> + + + +]]>
@@ -885,10 +885,10 @@ public class ExampleBean { explicitly by use of the index attribute. For example: - <bean id="exampleBean" class="examples.ExampleBean"> - <constructor-arg index="0" value="7500000"/> - <constructor-arg index="1" value="42"/> -</bean> + + + +]]> As well as solving the ambiguity problem of multiple simple values, specifying an index also solves the problem of ambiguity @@ -1099,7 +1099,7 @@ public class ExampleBean { <bean id="anotherExampleBean" class="examples.AnotherBean"/> <bean id="yetAnotherBean" class="examples.YetAnotherBean"/> - public class ExampleBean { + +}]]> As you can see, setters have been declared to match against the properties specified in the XML file. Find below an example of using @@ -1138,7 +1138,7 @@ public class ExampleBean { <bean id="anotherExampleBean" class="examples.AnotherBean"/> <bean id="yetAnotherBean" class="examples.YetAnotherBean"/> - public class ExampleBean { + +}]]> As you can see, the constructor arguments specified in the bean definition will be used to pass in as arguments to the constructor of @@ -1160,15 +1160,15 @@ public class ExampleBean { constructor, Spring is told to call a static factory method to return an instance of the object: - <bean id="exampleBean" class="examples.ExampleBean" - factory-method="createInstance"> - <constructor-arg ref="anotherExampleBean"/> - <constructor-arg ref="yetAnotherBean"/> - <constructor-arg value="1"/> -</bean> + + + + + -<bean id="anotherExampleBean" class="examples.AnotherBean"/> -<bean id="yetAnotherBean" class="examples.YetAnotherBean"/> + +]]> public class ExampleBean { @@ -1295,23 +1295,23 @@ public class ExampleBean { container (to a <constructor-arg/> or <property/> element). - <bean id="theTargetBean" class="..."/> + -<bean id="theClientBean" class="..."> - <property name="targetName"> - <idref bean="theTargetBean" /> - </property> -</bean> + + + + +]]> The above bean definition snippet is exactly equivalent (at runtime) to the following snippet: - <bean id="theTargetBean" class="..." /> + -<bean id="client" class="..."> - <property name="targetName" value="theTargetBean" /> -</bean> + + +]]> The main reason the first form is preferable to the second is that using the idref tag allows the container to @@ -1374,7 +1374,7 @@ public class ExampleBean { bean, or one of the values in the 'name' attribute of the target bean. - <ref bean="someBean"/> + ]]> Specifying the target bean by using the local attribute leverages the ability of the XML parser to validate XML id @@ -1386,7 +1386,7 @@ public class ExampleBean { about errors as early as possible) if the target bean is in the same XML file. - <ref local="someBean"/> + ]]> Specifying the target bean by using the 'parent' attribute allows a reference to be created @@ -1514,7 +1514,7 @@ public class ExampleBean { value, can also again be any of the following elements: - bean | ref | idref | list | set | map | props | value | null +
Collection merging @@ -1574,9 +1574,9 @@ public class ExampleBean { adminEmails collection with the parent's adminEmails collection. - administrator=administrator@example.com + +support=support@example.co.uk]]> Notice how the child Properties collection's value set will have inherited all the property elements @@ -1631,26 +1631,26 @@ support=support@example.co.uk instances will be converted to the appropriate type prior to being added to the Collection. - public class Foo { + accounts; - public void setAccounts(Map<String, Float> accounts) { + public void setAccounts(Map accounts) { this.accounts = accounts; } -} - - <beans> - <bean id="foo" class="x.y.Foo"> - <property name="accounts"> - <map> - <entry key="one" value="9.99"/> - <entry key="two" value="2.75"/> - <entry key="six" value="3.99"/> - </map> - </property> - </bean> -</beans> +}]]> + + + + + + + + + + + +]]> When the 'accounts' property of the 'foo' bean is being prepared for injection, the @@ -1675,18 +1675,18 @@ support=support@example.co.uk email property being set to the empty String value ("") - <bean class="ExampleBean"> - <property name="email"><value/></property> -</bean> + + +]]> This is equivalent to the following Java code: exampleBean.setEmail(""). The special <null> element may be used to indicate a null value. For example: - <bean class="ExampleBean"> - <property name="email"><null/></property> -</bean> + + +]]> The above configuration is equivalent to the following Java code: exampleBean.setEmail(null). @@ -1713,25 +1713,25 @@ support=support@example.co.uk embedding a full <value/> element. Therefore, the following: - <property name="myProperty"> - <value>hello</value> -</property> + + hello +]]> - <constructor-arg> - <value>hello</value> -</constructor-arg> + + hello +]]> - <entry key="myKey"> - <value>hello</value> -</entry> + + hello +]]> are equivalent to: - <property name="myProperty" value="hello"/> + ]]> - <constructor-arg value="hello"/> + ]]> - <entry key="myKey" value="hello"/> + ]]> The <property/> and <constructor-arg/> elements support a @@ -1739,19 +1739,19 @@ support=support@example.co.uk used instead of a full nested <ref/> element. Therefore, the following: - <property name="myProperty"> - <ref bean="myBean"> -</property> + + +]]> - <constructor-arg> - <ref bean="myBean"> -</constructor-arg> + + +]]> ... are equivalent to: - <property name="myProperty" ref="myBean"/> + ]]> - <constructor-arg ref="myBean"/> + ]]> Note however that the shortcut form is equivalent to a <ref bean="xxx"> element; there is no @@ -1764,16 +1764,16 @@ support=support@example.co.uk 'value' / 'value-ref' attributes. Therefore, the following: - <entry> - <key> - <ref bean="myKeyBean" /> - </key> - <ref bean="myValueBean" /> -</entry> + + + + + +]]> is equivalent to: - <entry key-ref="myKeyBean" value-ref="myValueBean"/> + ]]> Again, the shortcut form is equivalent to a <ref bean="xxx"> element; there is no shortcut for @@ -1807,19 +1807,19 @@ support=support@example.co.uk the end: the first is using the standard XML format whereas the second example is using the p-namespace. - <beans xmlns="http://www.springframework.org/schema/beans" + - <bean name="classic" class="com.example.ExampleBean"> - <property name="email" value="foo@bar.com/> - </bean> + + + +]]> As you can see, we are including an attribute in the p-namespace called email in the bean definition - this is telling @@ -1831,26 +1831,26 @@ support=support@example.co.uk This next example includes two more bean definitions that both have a reference to another bean: - <beans xmlns="http://www.springframework.org/schema/beans" + - <bean name="john-classic" class="com.example.Person"> - <property name="name" value="John Doe"/> - <property name="spouse" ref="jane"/> - </bean> + + + + - <bean name="john-modern" + - <bean name="jane" class="com.example.Person"> - <property name="name" value="Jane Doe"/> - </bean> -</beans> + + + +]]> As you can see, this example doesn't only include a property value using the p-namespace, but also uses a special format to @@ -1888,9 +1888,9 @@ support=support@example.co.uk the final property name are not null. Consider the following bean definition... - <bean id="foo" class="foo.Bar"> - <property name="fred.bob.sammy" value="123" /> -</bean> + + +]]> The foo bean has a fred property which has a bob property, which has a @@ -1932,12 +1932,12 @@ support=support@example.co.uk 'depends-on' attribute, with commas, whitespace and semicolons all valid delimiters, like so: - <bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao"> - <property name="manager" ref="manager" /> -</bean> + + + -<bean id="manager" class="ManagerBean" /> -<bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" /> + +]]> The 'depends-on' attribute at the bean @@ -2544,9 +2544,9 @@ public class ReplacementComputeValue implements MethodReplacer { fully qualified type name. For example, all the following would match java.lang.String. - java.lang.String + + Str]]> Since the number of arguments is often enough to distinguish between each possible choice, this shortcut can save a lot of typing, @@ -2873,13 +2873,13 @@ public class ReplacementComputeValue implements MethodReplacer { the declarations in your web application's 'web.xml' file. - <web-app> + ... - <listener> - <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> - </listener> + + org.springframework.web.context.request.RequestContextListener + ... -</web-app> +]]> If you are using an older web container (Servlet 2.3), you will need to use the provided @@ -2891,18 +2891,18 @@ public class ReplacementComputeValue implements MethodReplacer { mapping depends on the surrounding web application configuration and so you will have to change it as appropriate.) - <web-app> + .. - <filter> - <filter-name>requestContextFilter</filter-name> - <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> - </filter> - <filter-mapping> - <filter-name>requestContextFilter</filter-name> - <url-pattern>/*</url-pattern> - </filter-mapping> + + requestContextFilter + org.springframework.web.filter.RequestContextFilter + + + requestContextFilter + /* + ... -</web-app> +]]> That's it. DispatcherServlet, RequestContextListener and @@ -2918,7 +2918,7 @@ public class ReplacementComputeValue implements MethodReplacer { Consider the following bean definition: - <bean id="loginAction" class="com.foo.LoginAction" scope="request"/> + ]]> With the above bean definition in place, the Spring container will create a brand new instance of the @@ -2940,7 +2940,7 @@ public class ReplacementComputeValue implements MethodReplacer { Consider the following bean definition: - <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/> + ]]> With the above bean definition in place, the Spring container will create a brand new instance of the @@ -2967,7 +2967,7 @@ public class ReplacementComputeValue implements MethodReplacer { Consider the following bean definition: - <bean id="userPreferences" class="com.foo.UserPreferences" scope="globalSession"/> + ]]> The global session scope is similar to the standard HTTP Session scope (incomplete): - <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/> + -<bean id="userManager" class="com.foo.UserManager"> - <property name="userPreferences" ref="userPreferences"/> -</bean> + + +]]> From the above configuration it is evident that the singleton bean 'userManager' is being injected with a @@ -3204,7 +3204,7 @@ public class ReplacementComputeValue implements MethodReplacer { of the bean, after having bound it to the session for future reference). - Object get(String name, ObjectFactory objectFactory) + The second method should remove the object from the underlying scope. The session scope implementation for example, removes the @@ -3212,20 +3212,20 @@ public class ReplacementComputeValue implements MethodReplacer { returned (you are allowed to return null if the object with the specified name wasn't found) - Object remove(String name) + The third method is used to register callbacks the scope should execute when it is destroyed or when the specified object in the scope is destroyed. Please refer to the Javadoc or a Spring scope implementation for more information on destruction callbacks. - void registerDestructionCallback(String name, Runnable destructionCallback) + The last method deals with obtaining the conversation identifier for the underlying scope. This identifier is different for each scope. For a session for example, this can be the session identifier. - String getConversationId() +
@@ -3241,7 +3241,7 @@ public class ReplacementComputeValue implements MethodReplacer { BeanFactory implementations that ship with Spring); this central method is displayed below: - void registerScope(String scopeName, Scope scope); + The first argument to the registerScope(..) method is the unique name @@ -3358,7 +3358,7 @@ beanFactory.registerScope("thread", customScope InitializingBean interface specifies exactly one method: - void afterPropertiesSet() throws Exception; + Generally, the use of the InitializingBean interface can be @@ -3369,7 +3369,7 @@ beanFactory.registerScope("thread", customScope 'init-method' attribute. For example, the following definition: - <bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/> + ]]> public class ExampleBean { @@ -3380,7 +3380,7 @@ beanFactory.registerScope("thread", customScope ...is exactly the same as... - <bean id="exampleInitBean" class="examples.AnotherExampleBean"/> + ]]> public class AnotherExampleBean implements InitializingBean { @@ -3402,7 +3402,7 @@ beanFactory.registerScope("thread", customScope DisposableBean interface specifies a single method: - void destroy() throws Exception; + Generally, the use of the DisposableBean callback interface can @@ -3414,7 +3414,7 @@ beanFactory.registerScope("thread", customScope <bean/>. For example, the following definition: - <bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/> + ]]> public class ExampleBean { @@ -3425,7 +3425,7 @@ beanFactory.registerScope("thread", customScope ...is exactly the same as... - <bean id="exampleInitBean" class="examples.AnotherExampleBean"/> + ]]> public class AnotherExampleBean implements DisposableBean { @@ -3666,10 +3666,10 @@ public final class Boot { BeanFactory that created it, when it is created by that BeanFactory. - public interface BeanFactoryAware { + +}]]> This allows beans to manipulate the BeanFactory that created them @@ -3712,7 +3712,7 @@ public final class Boot { ObjectFactoryCreatingFactoryBean with the name of the bean that is to be looked up. Let's look at an example: - package x.y; + +}]]> - package x.y; + +}]]> Find below the XML configuration to wire together the above classes using the ObjectFactoryCreatingFactoryBean approach. - <beans> - <bean id="newsFeedManager" class="x.y.NewsFeedManager"> - <property name="factory"> - <bean -class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean"> - <property name="targetBeanName"> - <idref local="newsFeed" /> - </property> - </bean> - </property> - </bean> - <bean id="newsFeed" class="x.y.NewsFeed" scope="prototype"> - <property name="news" value="... that's fit to print!" /> - </bean> -</beans> + + + + + + + + + + + + + +]]> And here is a small driver program to test the fact that new (prototype) instances of the newsFeed bean are @@ -3775,7 +3775,7 @@ class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean NewsFeedManager's printNews() method. - import org.springframework.context.ApplicationContext; + +}]]> The output from running the above program will look like so (results will of course vary on your machine). - x.y.NewsFeed@1292d26: '... that's fit to print!' -x.y.NewsFeed@5329c5: '... that's fit to print!' + As of Spring 2.5, you can rely upon autowiring of the BeanFactory as yet another alternative @@ -4137,7 +4137,7 @@ public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor Find below a small driver script to exercise the above code and configuration; - import org.springframework.context.ApplicationContext; + +}]]> The output of executing the above program will be (something like) this: - Bean 'messenger' created : org.springframework.scripting.groovy.GroovyMessenger@272961 -org.springframework.scripting.groovy.GroovyMessenger@272961 +
@@ -4315,10 +4315,10 @@ cfg.postProcessBeanFactory(factory); The actual values come from another file in the standard Java Properties format: - jdbc.driverClassName=org.hsqldb.jdbcDriver + +jdbc.password=root]]> With the context namespace introduced in Spring 2.5, it is possible to configure property placeholders with a @@ -4326,7 +4326,7 @@ jdbc.password=root a comma-separated list for the location attribute. - <context:property-placeholder location="classpath:com/foo/jdbc.properties"/> + ]]> The PropertyPlaceholderConfigurer doesn't only look for properties in the Properties file @@ -4349,16 +4349,16 @@ jdbc.password=root you have to pick a particular implementation class at runtime. For example: - <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> - <property name="locations"> - <value>classpath:com/foo/strategy.properties</value> - </property> - <property name="properties"> - <value>custom.strategy.class=com.foo.DefaultStrategy</value> - </property> -</bean> + + + classpath:com/foo/strategy.properties + + + custom.strategy.class=com.foo.DefaultStrategy + + -<bean id="serviceStrategy" class="${custom.strategy.class}"/> +]]> If the class is unable to be resolved at runtime to a valid class, resolution of the bean will fail once it is about to be @@ -4392,12 +4392,12 @@ jdbc.password=root Properties file configuration lines are expected to be in the format: - beanName.property=value + An example properties file might look like this: - dataSource.driverClassName=com.mysql.jdbc.Driver -dataSource.url=jdbc:mysql:mydb + This example file would be usable against a container definition which contains a bean called dataSource, which @@ -4409,7 +4409,7 @@ dataSource.url=jdbc:mysql:mydb is already non-null (presumably initialized by the constructors). In this example... - foo.fred.bob.sammy=123 + ... the sammy property of the bob property of the fred @@ -4425,7 +4425,7 @@ dataSource.url=jdbc:mysql:mydb Spring 2.5, it is possible to configure property overriding with a dedicated configuration element: - <context:property-override location="classpath:override.properties"/> + ]]>
@@ -4718,18 +4718,18 @@ dataSource.url=jdbc:mysql:mydb source. The ResourceBundleMessageSource is more interesting and is the one we will provide an example for: - <beans> - <bean id="messageSource" - class="org.springframework.context.support.ResourceBundleMessageSource"> - <property name="basenames"> - <list> - <value>format</value> - <value>exceptions</value> - <value>windows</value> - </list> - </property> - </bean> -</beans> + + + + + format + exceptions + windows + + + +]]> This assumes you have three resource bundles defined on your classpath called format, @@ -4752,15 +4752,15 @@ argument.required=The '{0}' argument is required. implementations and so can be cast to the MessageSource interface. - public static void main(String[] args) { + +}]]> The resulting output from the above program will be... - Alligators rock! + So to summarize, the MessageSource is defined in a file called 'beans.xml' (this file @@ -4792,7 +4792,7 @@ argument.required=The '{0}' argument is required. </beans> - public class Example { + System.out.println(message); } -} +}]]> The resulting output from the invocation of the execute() method will be... - The 'userDao' argument is required. + With regard to internationalization (i18n), Spring's various MessageResource implementations follow the same @@ -4831,17 +4831,17 @@ argument.required=The '{0}' argument is required. # in 'exceptions_en_GB.properties' argument.required=Ebagum lad, the '{0}' argument is required, I say, required. - public static void main(final String[] args) { + +}]]> The resulting output from the running of the above program will be... - Ebagum lad, the 'userDao' argument is required, I say, required. + The MessageSourceAware interface can also be used to acquire a reference to any @@ -4988,19 +4988,19 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.Let's look at an example. First, the ApplicationContext: - <bean id="emailer" class="example.EmailBean"> - <property name="blackList"> - <list> - <value>black@list.org</value> - <value>white@list.org</value> - <value>john@doe.org</value> - </list> - </property> -</bean> + + + + black@list.org + white@list.org + john@doe.org + + + -<bean id="blackListListener" class="example.BlackListNotifier"> - <property name="notificationAddress" value="spam@list.org"/> -</bean> + + +]]> Now, let's look at the actual classes: @@ -5296,10 +5296,8 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.@Resource, @PostConstruct, and - @PreDestroy. Of course, these options are - only available if you are using at least Java 5 (Tiger) and thus have - access to source level annotations. Use of these annotations also requires - that certain BeanPostProcessors be + @PreDestroy. Use of these annotations also + requires that certain BeanPostProcessors be registered within the Spring container. As always, these can be registered as individual bean definitions, but they can also be implicitly registered by including the following tag in an XML-based Spring configuration @@ -5731,12 +5729,12 @@ public @interface Genre { Internet connection is available. First define the simple annotation: - @Target({ElementType.FIELD, ElementType.PARAMETER}) + +}]]> Then add the annotation to the field or property to be autowired: @@ -5766,7 +5764,7 @@ public @interface Offline { be considered an autowire candidate. As an example, consider the following annotation definition: - @Target({ElementType.FIELD, ElementType.PARAMETER}) + +}]]> In this case Format is an enum: - public enum Format { + +}]]> The fields to be autowired are annotated with the custom qualifier and include values for both attributes: 'genre' and @@ -5870,13 +5868,13 @@ public @interface MovieQualifier { even if they are not themselves annotated with Spring's @Qualifier annotation. - <bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"> - <property name="customQualifierTypes"> - <set> - <value>example.CustomQualifier</value> - </set> - </property> -</bean> + + + + example.CustomQualifier + + +]]> Note that the particular implementation of AutowireCandidateResolver that will be @@ -6028,6 +6026,327 @@ public @interface MovieQualifier { +
+ Java-based configuration + + Starting with Spring 3.0 many of the features provided by the Spring JavaConfig + project have been added to the core Spring Framework. This allows + you to define beans using Java rather than using the traditional XML + files. + + The central artifact in Spring's new Java-configuration support is + the @Configuration-annotated class. These + classes consist principally of + @Bean-annotated methods that define + instantiation, configuration, and initialization logic for objects that + will be managed by the Spring IoC container. + +
+ Using the <interfacename>@Configuration</interfacename> + annotation + + Annotating a class with the + @Configuration indicates that the class + may be used by the Spring IoC container as a source of bean definitions. + The simplest possible @Configuration + class would read as follows: + + An application may make use of just one + @Configuration-annotated class, or many. + @Configuration is meta-annotated as a + @Component, therefore + Configuration-classes are candidates for component-scanning and may also + take advantage of @Autowired annotations + at the field and method level but not at the constructor level. + Configuration-classes must also have a default constructor. Externalized + values may be wired into Configuration-classes using the + @Value annotation. +
+ +
+ Using the <interfacename>@Bean</interfacename> annotation + + @Bean is a method-level annotation + and a direct analog of the XML <bean/> element. The + annotation supports most of the attributes offered by + <bean/>, such as: init-method, + destroy-method, + autowiring, + lazy-init, + dependency-check, + depends-on + and scope. + +
+ Declaring a bean + + To declare a bean, simply annotate a method with the + @Bean annotation. When JavaConfig + encounters such a method, it will execute that method and register the + return value as a bean within a BeanFactory. By default, + the bean name will be the same as the method name (see bean naming for details on how to + customize this behavior). The following is a simple example of a + @Bean method declaration: + + + For comparison sake, the configuration above is exactly + equivalent to the following Spring XML: + + ]]> + + Both will result in a bean named transferService + being available in the BeanFactory or + ApplicationContext, bound to an object instance of type + TransferServiceImpl: com.acme.TransferServiceImpl + ]]> +
+ +
+ Injecting dependencies + + When @Beans have dependencies on + one another, expressing that dependency is as simple as having one + bean method call another: + + In the example above, the foo bean recevies a + reference to bar via constructor injection. +
+ +
+ Receiving lifecycle callbacks + + Beans created in a Configuration-class supports the regular + lifecycle callbacks. Any classes defined with the @Bean annotation can + use the @PostConstruct and @PreDestroy annotations from JSR-250, see + the section on JSR-250 + annotations for further details. + + The regular Spring lifecycle callbacks are fully + supported as well. If a bean implements InitializingBean, + DisposableBean, or Lifecycle, their + respective methods will be called by the container. + + The standard set of *Aware interfaces such as + BeanFactoryAware, + BeanNameAware, + MessageSourceAware, + ApplicationContextAware, + etc. are also fully supported. + + The @Bean annotation supports + specifying arbitrary initialization and destruction callback methods, + much like Spring XML's init-method and + destroy-method attributes to the bean + element: + + Of course, in the case of Foo above, it would be + equally as valid to call the init() method directly + during construction: + + + Remember that because you are working directly in Java, you + can do anything you like with your objects, and do not always need + to rely on the container! + +
+ +
+ Specifying bean scope + +
+ Using the <interfacename>@Scope</interfacename> + annotation + + You can specify that your beans defined with the + @Bean annotation should have a + specific scope. You can use any of the standard scopes specified in + the Bean Scopes + section. + + The StandardScopes class provides string + constants for each of these four scopes. SINGLETON is the default, + and can be overridden by using the + @Scope annotation: +
+ +
+ <code>@Scope and scoped-proxy</code> + + Spring offers a convenient way of working with scoped + dependencies through scoped + proxies. The easiest way to create such a proxy when using + the XML configuration is the <aop:scoped-proxy/> + element. Configuring your beans in Java with a @Scope annotation + offers equivalent support with the proxyMode attribute. The default + is no proxy (ScopedProxyMode.NO) but you can + specify ScopedProxyMode.TARGET_CLASS or + ScopedProxyMode.INTERFACES. + + If we were to port the the XML reference documentation scoped + proxy example (see link above) to our + @Bean using Java, it would look like + the following: +
+ +
+ Lookup method injection + + As noted in the core documentation, lookup method + injection is an advanced feature that should be comparatively + rarely used. It is useful in cases where a singleton-scoped bean has + a dependency on a prototype-scoped bean. JavaConfig provides a + natural means for implementing this pattern. Note that the + example below is adapted from the example classes and configuration + in the core documentation linked above. + + JavaConfig can easily create a subclass of + CommandManager where the abstract + createCommand() is overridden in such a way that it + 'looks up' a brand new (prototype) command object: +
+
+ +
+ Customizing bean naming + + By default, Configuration-classes uses a + @Bean method's name as the name of the + resulting bean. This functionality can be overridden, however, using + the name attribute. +
+
+
+
Classpath scanning for managed components @@ -6096,7 +6415,7 @@ public @interface MovieQualifier { ApplicationContext. For example, the following two classes are eligible for such autodetection: - @Service + +}]]> @Repository public class JpaMovieFinder implements MovieFinder { @@ -6118,18 +6437,18 @@ public class JpaMovieFinder implements MovieFinder { alternatively a comma-separated list could be specified that included the parent package of each class). - <?xml version="1.0" encoding="UTF-8"?> -<beans xmlns="http://www.springframework.org/schema/beans" + + - <context:component-scan base-package="org.example"/> + -</beans> +]]> Note that the scanning of classpath packages requires the @@ -6246,14 +6565,14 @@ public class JpaMovieFinder implements MovieFinder { @Repository annotations and using "stub" repositories instead. - <beans ...> + - <context:component-scan base-package="org.example"> - <context:include-filter type="regex" expression=".*Stub.*Repository"/> - <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> - </context:component-scan> + + + + -</beans> +]]> It is also possible to disable the default filters by providing @@ -6306,12 +6625,12 @@ public class MovieFinderImpl implements MovieFinder { scanner: - <beans ...> + - <context:component-scan base-package="org.example" - name-generator="org.example.MyNameGenerator" /> + -</beans> +]]> As a general rule, consider specifying the name with the annotation whenever other components may be making explicit references @@ -6344,12 +6663,12 @@ public class MovieFinderImpl implements MovieFinder { scanner: - <beans ...> + - <context:component-scan base-package="org.example" - scope-resolver="org.example.MyScopeResolver" /> + -</beans> +]]> When using certain non-singleton scopes, it may be necessary to generate proxies for the scoped objects. The reasoning is described in @@ -6360,12 +6679,12 @@ public class MovieFinderImpl implements MovieFinder { 'interfaces', and 'targetClass'. For example, the following configuration will result in standard JDK dynamic proxies: - <beans ...> + - <context:component-scan base-package="org.example" - scoped-proxy="interfaces" /> + -</beans> +]]>
@@ -6423,7 +6742,7 @@ public class CachingMovieCatalog implements MovieCatalog { @Configuration annotated classes. Here is a simple example - @Component + +}]]> This class is a Spring component and has application specific code contained in its DoWork method. However, it @@ -6449,7 +6768,7 @@ public class FactoryMethodComponent { fields and methods are supported as before with the additional support for autowiring of @Bean methods, as shown in the example below - @Component + +]]> Note the use of autowiring of the String method parameter country to the value of the @@ -6511,11 +6830,11 @@ public class FactoryMethodComponent { The context namespace introduced in Spring 2.5 provides a load-time-weaver element. - <beans ...> + - <context:load-time-weaver/> + -</beans> +]]> Adding this element to an XML-based Spring configuration file activates a Spring LoadTimeWeaver for the @@ -6529,4 +6848,4 @@ public class FactoryMethodComponent { for more detail. For more on AspectJ load-time weaving, see .
-
+ \ No newline at end of file diff --git a/spring-framework-reference/src/spring-framework-reference.xml b/spring-framework-reference/src/spring-framework-reference.xml index b76f93f2603..57cc693e6b1 100644 --- a/spring-framework-reference/src/spring-framework-reference.xml +++ b/spring-framework-reference/src/spring-framework-reference.xml @@ -95,16 +95,20 @@ Arjen Poutsma - - Tareq - Abed Rabbo - + + Chris + Beams + + + Tareq + Abed Rabbo + 2004-2009 Rod Johnson, Juergen Hoeller, Alef Arendsen, Colin Sampaleanu, Rob Harrop, Thomas Risberg, Darren Davison, Dmitriy Kopylenko, Mark Pollack, Thierry Templier, Erwin Vervaet, Portia Tung, Ben Hale, Adrian Colyer, John Lewis, - Costin Leau, Mark Fisher, Sam Brannen, Ramnivas Laddad, Arjen Poutsma, Tareq Abbed Rabbo + Costin Leau, Mark Fisher, Sam Brannen, Ramnivas Laddad, Arjen Poutsma, Chris Beams, Tareq Abbed Rabbo