diff --git a/spring-framework-reference/src/beans.xml b/spring-framework-reference/src/beans.xml index 333fd0b2a80..0b6ddda8af5 100644 --- a/spring-framework-reference/src/beans.xml +++ b/spring-framework-reference/src/beans.xml @@ -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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> - - - + <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" class="examples.ExampleBean2" - factory-method="createInstance"/>]]> + 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 { private AnotherBean beanOne; private YetAnotherBean beanTwo; @@ -1116,7 +1116,7 @@ public class ExampleBean { public void setIntegerProperty(int i) { this.i = i; } -}]]> +} 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 { private AnotherBean beanOne; private YetAnotherBean beanTwo; @@ -1150,7 +1150,7 @@ public class ExampleBean { this.beanTwo = yetAnotherBean; this.i = i; } -}]]> +} 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 sales=sales@example.com -support=support@example.co.uk]]> +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 { - private Map accounts; + private Map<String, Float> accounts; - public void setAccounts(Map accounts) { + public void setAccounts(Map<String, Float> 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: - - hello -]]> + <property name="myProperty"> + <value>hello</value> +</property> - - hello -]]> + <constructor-arg> + <value>hello</value> +</constructor-arg> - - hello -]]> + <entry key="myKey"> + <value>hello</value> +</entry> 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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> - - - + <bean name="classic" class="com.example.ExampleBean"> + <property name="email" value="foo@bar.com"/> + </bean> - -]]> + <bean name="p-namespace" class="com.example.ExampleBean" + p:email="foo@bar.com"/> +</beans> 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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> - - - - + <bean name="john-classic" class="com.example.Person"> + <property name="name" value="John Doe"/> + <property name="spouse" ref="jane"/> + </bean> - + p:spouse-ref="jane"/> - - - -]]> + <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 @@ -2545,9 +2545,9 @@ public class ReplacementComputeValue implements MethodReplacer { fully qualified type name. For example, all the following would match java.lang.String. - java.lang.String String - Str]]> + Str Since the number of arguments is often enough to distinguish between each possible choice, this shortcut can save a lot of typing, @@ -2874,13 +2874,13 @@ public class ReplacementComputeValue implements MethodReplacer { the declarations in your web application's 'web.xml' file. - + <web-app> ... - - org.springframework.web.context.request.RequestContextListener - + <listener> + <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> + </listener> ... -]]> +</web-app> If you are using an older web container (Servlet 2.3), you will need to use the provided @@ -2892,18 +2892,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> .. - - requestContextFilter - org.springframework.web.filter.RequestContextFilter - - - requestContextFilter - /* - + <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> ... -]]> +</web-app> That's it. DispatcherServlet, RequestContextListener and @@ -2919,7 +2919,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 @@ -2941,7 +2941,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 @@ -2968,7 +2968,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 @@ -3205,7 +3205,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 @@ -3213,20 +3213,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()
@@ -3242,7 +3242,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 @@ -3359,7 +3359,7 @@ beanFactory.registerScope("thread", customScope InitializingBean interface specifies exactly one method: - + void afterPropertiesSet() throws Exception; Generally, the use of the InitializingBean interface can be @@ -3370,7 +3370,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 { @@ -3381,7 +3381,7 @@ beanFactory.registerScope("thread", customScope ...is exactly the same as... - ]]> + <bean id="exampleInitBean" class="examples.AnotherExampleBean"/> public class AnotherExampleBean implements InitializingBean { @@ -3403,7 +3403,7 @@ beanFactory.registerScope("thread", customScope DisposableBean interface specifies a single method: - + void destroy() throws Exception; Generally, the use of the DisposableBean callback interface can @@ -3415,7 +3415,7 @@ beanFactory.registerScope("thread", customScope <bean/>. For example, the following definition: - ]]> + <bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/> public class ExampleBean { @@ -3426,7 +3426,7 @@ beanFactory.registerScope("thread", customScope ...is exactly the same as... - ]]> + <bean id="exampleInitBean" class="examples.AnotherExampleBean"/> public class AnotherExampleBean implements DisposableBean { @@ -3667,10 +3667,10 @@ public final class Boot { BeanFactory that created it, when it is created by that BeanFactory. - public interface BeanFactoryAware { void setBeanFactory(BeanFactory beanFactory) throws BeansException; -}]]> +} This allows beans to manipulate the BeanFactory that created them @@ -3713,7 +3713,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; public class NewsFeed { @@ -3726,9 +3726,9 @@ public class NewsFeed { public String getNews() { return this.toString() + ": '" + news + "'"; } -}]]> +} - package x.y; import org.springframework.beans.factory.ObjectFactory; @@ -3746,28 +3746,28 @@ public class NewsFeedManager { NewsFeed news = (NewsFeed) factory.getObject(); System.out.println(news.getNews()); } -}]]> +} 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 @@ -3776,7 +3776,7 @@ class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean NewsFeedManager's printNews() method. - import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import x.y.NewsFeedManager; @@ -3789,13 +3789,13 @@ public class Main { manager.printNews(); manager.printNews(); } -}]]> +} 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 @@ -4138,7 +4138,7 @@ public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor Find below a small driver script to exercise the above code and configuration; - import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.scripting.Messenger; @@ -4149,13 +4149,13 @@ public final class Boot { Messenger messenger = (Messenger) ctx.getBean("messenger"); System.out.println(messenger); } -}]]> +} 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
@@ -4316,10 +4316,10 @@ cfg.postProcessBeanFactory(factory); The actual values come from another file in the standard Java Properties format: - jdbc.driverClassName=org.hsqldb.jdbcDriver jdbc.url=jdbc:hsqldb:hsql://production:9002 jdbc.username=sa -jdbc.password=root]]> +jdbc.password=root With the context namespace introduced in Spring 2.5, it is possible to configure property placeholders with a @@ -4327,7 +4327,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 @@ -4350,16 +4350,16 @@ jdbc.password=root]]> you have to pick a particular implementation class at runtime. For example: - - - classpath:com/foo/strategy.properties - - - custom.strategy.class=com.foo.DefaultStrategy - - + <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> -]]> +<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 @@ -4393,12 +4393,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 @@ -4410,7 +4410,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 @@ -4426,7 +4426,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"/>
@@ -4719,18 +4719,18 @@ dataSource.url=jdbc:mysql:mydb]]> source. The ResourceBundleMessageSource is more interesting and is the one we will provide an example for:
- - - - - format - exceptions - windows - - - -]]> + <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> This assumes you have three resource bundles defined on your classpath called format, @@ -4753,15 +4753,15 @@ argument.required=The '{0}' argument is required. implementations and so can be cast to the MessageSource interface. - public static void main(String[] args) { MessageSource resources = new ClassPathXmlApplicationContext("beans.xml"); String message = resources.getMessage("message", null, "Default", null); System.out.println(message); -}]]> +} 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 @@ -4793,7 +4793,7 @@ argument.required=The '{0}' argument is required. </beans> - public class Example { private MessageSource messages; @@ -4807,12 +4807,12 @@ argument.required=The '{0}' argument is required. 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 @@ -4832,17 +4832,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) { MessageSource resources = new ClassPathXmlApplicationContext("beans.xml"); String message = resources.getMessage("argument.required", new Object [] {"userDao"}, "Required", Locale.UK); System.out.println(message); -}]]> +} 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 @@ -4989,19 +4989,19 @@ argument.required=Ebagum lad, the '{0}' argument is required, I say, required.Let's look at an example. First, the ApplicationContext: - - - - black@list.org - white@list.org - john@doe.org - - - + <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> - - -]]> +<bean id="blackListListener" class="example.BlackListNotifier"> + <property name="notificationAddress" value="spam@list.org"/> +</bean> Now, let's look at the actual classes: @@ -5730,12 +5730,12 @@ public @interface Genre { Internet connection is available. First define the simple annotation: - @Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface Offline { -}]]> +} Then add the annotation to the field or property to be autowired: @@ -5765,7 +5765,7 @@ public @interface Offline { be considered an autowire candidate. As an example, consider the following annotation definition: - @Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface MovieQualifier { @@ -5773,14 +5773,14 @@ public @interface MovieQualifier { String genre(); Format format(); -}]]> +} In this case Format is an enum: - public enum Format { VHS, DVD, BLURAY -}]]> +} The fields to be autowired are annotated with the custom qualifier and include values for both attributes: 'genre' and @@ -5869,13 +5869,13 @@ public @interface MovieQualifier { even if they are not themselves annotated with Spring's @Qualifier annotation. - - - - example.CustomQualifier - - -]]> + <bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"> + <property name="customQualifierTypes"> + <set> + <value>example.CustomQualifier</value> + </set> + </property> +</bean> Note that the particular implementation of AutowireCandidateResolver that will be @@ -6107,7 +6107,7 @@ public @interface MovieQualifier { ApplicationContext. For example, the following two classes are eligible for such autodetection: - @Service public class SimpleMovieLister { private MovieFinder movieFinder; @@ -6116,7 +6116,7 @@ public class SimpleMovieLister { public SimpleMovieLister(MovieFinder movieFinder) { this.movieFinder = movieFinder; } -}]]> +} @Repository public class JpaMovieFinder implements MovieFinder { @@ -6129,18 +6129,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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - + <context:component-scan base-package="org.example"/> -]]> +</beans> Note that the scanning of classpath packages requires the @@ -6257,14 +6257,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 @@ -6293,10 +6293,10 @@ public class JpaMovieFinder implements MovieFinder { @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: @Configuration public class AppConfig { -} ]]> +} An application may make use of one @Configuration-annotated class, or many. @@ -6338,7 +6338,7 @@ public class AppConfig { linkend="bean-naming"> bean naming for details on how to customize this behavior). The following is a simple example of a @Bean method declaration: - @Configuration public class AppConfig { @Bean @@ -6346,20 +6346,20 @@ public class AppConfig { return new TransferServiceImpl(); } -} ]]> +} For comparison sake, the configuration above is exactly equivalent to the following Spring XML: - - ]]> + language="xml"><beans> + <bean name="transferService" class="com.acme.TransferServiceImpl"/> +</beans> 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 - ]]> + TransferServiceImpl: +transferService -> com.acme.TransferServiceImpl +
@@ -6367,7 +6367,7 @@ transferService -> com.acme.TransferServiceImpl When @Beans have dependencies on one another, expressing that dependency is as simple as having one - bean method call another: @Configuration public class AppConfig { @Bean @@ -6380,7 +6380,7 @@ public class AppConfig { return new Bar(); } -} ]]> +} In the example above, the foo bean recevies a reference to bar via constructor injection. @@ -6417,7 +6417,7 @@ public class AppConfig { specifying arbitrary initialization and destruction callback methods, much like Spring XML's init-method and destroy-method attributes to the bean - element: public class Foo { public void init() { // initialization logic } @@ -6440,11 +6440,11 @@ public class AppConfig { return new Bar(); } } -]]> + Of course, in the case of Foo above, it would be equally as valid to call the init() method directly - during construction: @Configuration public class AppConfig { @Bean public Foo foo() { @@ -6454,7 +6454,7 @@ public class AppConfig { } // ... -} ]]> +} Remember that because you are working directly in Java, you @@ -6480,14 +6480,14 @@ public class AppConfig { constants for each of these four scopes. SINGLETON is the default, and can be overridden by using the @Scope annotation: @Configuration public class MyConfiguration { @Bean @Scope(StandardScopes.PROTOTYPE) public Encryptor encryptor() { // ... } -} ]]> +}
@@ -6507,7 +6507,7 @@ public class MyConfiguration { 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: // a HTTP Session-scoped bean exposed as a proxy @Bean @Scope(value = StandardScopes.SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public UserPreferences userPreferences() { @@ -6520,7 +6520,7 @@ public Service userService() { // a reference to the proxied 'userPreferences' bean service.seUserPreferences(userPreferences()); return service; -} ]]> +}
@@ -6532,7 +6532,7 @@ public Service userService() { rarely used. It is useful in cases where a singleton-scoped bean has a dependency on a prototype-scoped bean. Using Java for this type of configuration provides a natural means for implementing this - pattern. public abstract class CommandManager { public Object process(Object commandState) { // grab a new instance of the appropriate Command interface Command command = createCommand(); @@ -6544,13 +6544,13 @@ public Service userService() { // okay... but where is the implementation of this method? protected abstract Command createCommand(); -} ]]> +} Using Java-configuration support we 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: @Bean @Scope(StandardScopes.PROTOTYPE) public AsyncCommand asyncCommand() { AsyncCommand command = new AsyncCommand(); @@ -6567,7 +6567,7 @@ public CommandManager commandManager() { return asyncCommand(); } } -} ]]> +}
@@ -6577,8 +6577,7 @@ public CommandManager commandManager() { 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. name attribute. @Configuration public class AppConfig { @Bean(name = "bar") @@ -6586,7 +6585,7 @@ public class AppConfig { return new Foo(); } -} ]]> +} @@ -6599,7 +6598,7 @@ public class AppConfig { @Configuration annotated classes. Here is a simple example - @Component public class FactoryMethodComponent { @Bean @Qualifier("public") @@ -6611,7 +6610,7 @@ public class FactoryMethodComponent { { // Component method implementation omitted } -}]]> +} This class is a Spring component and has application specific code contained in its DoWork method. However, it @@ -6625,7 +6624,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 public class FactoryMethodComponent { private static int i; @@ -6655,7 +6654,7 @@ public class FactoryMethodComponent { return new TestBean("requestScopedInstance", 3); } } -]]> + Note the use of autowiring of the String method parameter country to the value of the @@ -6719,12 +6718,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 @@ -6757,12 +6756,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 @@ -6773,12 +6772,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>
@@ -6834,11 +6833,11 @@ public class CachingMovieCatalog implements MovieCatalog { 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