diff --git a/spring-framework-reference/src/beans.xml b/spring-framework-reference/src/beans.xml index bd31f42203b..889fed31376 100644 --- a/spring-framework-reference/src/beans.xml +++ b/spring-framework-reference/src/beans.xml @@ -22,9 +22,8 @@ url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/context/ApplicationContext.html">ApplicationContext is a sub-interface of BeanFactory. It adds easier integration with Spring's AOP features; message resource handling - (for use in internationalization, event propagation, and application-layer - in internationalization); event publication; and application-layer - specific contexts such as the + (for use in internationalization), event publication; and + application-layer specific contexts such as the WebApplicationContext for use in web applications. @@ -47,15 +46,9 @@ Beans, and the dependencies between them, are reflected in the configuration metadata used by a container. - - This chapter is divided into two parts, with the first part covering Inversion of Control - features and the second part - covering additional application framework features such as event - publication and internationalization. -
+
The Spring IoC container The interface @@ -68,25 +61,30 @@ express the objects that compose your application and the rich interdependencies between such objects. - Some implementations of the - ApplicationContext interface are supplied - out-of-the-box with Spring. In standalone applications it is common to - create an instance of Spring provides implementations of the + ApplicationContext interface for use in standalone + and web applications. In standalone applications it is common to create an + instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext. - This is because XML is the traditional format for defining configuration - metadata. To support the mixing of different configuration metadata - formats, use the GenericApplicationContext - implementation. + While XML has been the traditional format for defining configuration + metadata you instruct the container to use Java annotations or code as the + metadata format by providng a small amount of XML configuration to + declaratively enable support for using these additional metadata + formats. In most application scenarios, explicit user code is not required to instantiate one or more instances of a Spring IoC container. For example, - in a web application scenario, a simple eight (or so) lines of boilerplate - J2EE web descriptor XML in the web.xml file of the - application will typically suffice (see ). + in a web application scenario you configure the use of the + WebApplicationContext using simple eight (or so) lines of boilerplate J2EE + web descriptor XML in the web.xml file (see ). If you are using the SpringSource Tool + Suite Eclipse-powered development environment or Spring Roo this boilerplate + configuration can be easily created with few mouse clicks or + keystrokes. The following diagram is a high-level view of how Spring works. Your application classes are combined with configuration metadata so that after @@ -94,12 +92,7 @@ you have a fully configured and executable system or application. - - - - - + @@ -114,7 +107,7 @@ a form of configuration metadata; this configuration metadata represents how you as an application developer tell the Spring container to instantiate, configure, and assemble the - objects in your application. + objects in your application. Configuration metadata is traditionally supplied in a simple and intuitive XML format, which is what most of this chapter uses to convey @@ -153,9 +146,9 @@ Spring configuration consists of at least one and typically more than one bean definition that the container must manage. XML-based - configuration metadata shows these beans configured as - <bean/> elements inside a top-level - <beans/> element. + configuration represents beans as <bean/> + elements inside a top-level <beans/> + element. These bean definitions correspond to the actual objects that make up your application. Typically you define service layer objects, data @@ -210,12 +203,17 @@ metadata from a variety of external resources such as the local file system, from the Java CLASSPATH, and so on. - ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"}); + ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", + "daos.xml"}); After you learn about Spring's IoC container, you may want to know more about Spring's Resource - abstraction, as described in . + abstraction, as described in , which + provides a convenient mechanism for reading an InputSream from + locations defined in a URI syntax. In particular, the use of + Resource paths to construct applications + contexts as described in . The following example shows the service layer objects @@ -229,7 +227,8 @@ <!-- services --> - <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl"> + <bean id="petStore" + class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl"> <property name="accountDao" ref="accountDao"/> <property name="itemDao" ref="itemDao"/> <!-- additional collaborators and configuration for this bean go here --> @@ -241,7 +240,7 @@ The following example shows the data access objects - daos.xml) file: + (daos.xml) configuration file: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -322,7 +321,7 @@ dependency on a file that is outside the current application. This is in particular not recommended for "classpath:" URLs (for example, "classpath:../services.xml"), where the runtime resolution process - chooses the "nearest" classpath root and then looks into its parent + selects the "nearest" classpath root and then looks into its parent directory. Classpath configuration changes may lead to the choice of a different, incorrect directory. @@ -331,8 +330,10 @@ "classpath:/config/services.xml". However, be aware that you are coupling your application's configuration to specific absolute locations. It is generally preferable to keep an indirection for - such absolute locations, for example, through "${...}" placeholders - that are resolved against JVM system properties at runtime. + such absolute locations, for example, through property + placeholders, "${...}", that are resolved against JVM system + properties at runtime.
@@ -359,15 +360,15 @@ PetStoreServiceImpl service = context.getBean("petStore", PetStoreServiceImpl.cl List userList service.getUsernameList(); - You use getBean to retrieve instances of - your beans. The ApplicationContext - interface has a few other methods for retrieving beans, but ideally your - application code should never use them. Indeed, your application code - should have no calls to the getBean method at - all, and thus no dependency on Spring APIs at all. For example, Spring's - integration with web frameworks provides for dependency injection for - various web framework classes such as controllers and JSF-managed - beans. + You use the method getBean to retrieve + instances of your beans. The + ApplicationContext interface has a few + other methods for retrieving beans, but ideally your application code + should never use them. Indeed, your application code should have no + calls to the getBean method at all, and thus no + dependency on Spring APIs at all. For example, Spring's integration with + web frameworks provides for dependency injection for various web + framework classes such as controllers and JSF-managed beans. @@ -376,8 +377,8 @@ List userList service.getUsernameList(); A Spring IoC container manages one or more beans. These beans are created using the - configuration metadata that you supply to the container, typically in the - form of XML <bean/> definitions. + configuration metadata that you supply to the container, for example, in + the form of XML <bean/> definitions. Within the container itself, these bean definitions are represented as BeanDefinition objects, which contain @@ -505,17 +506,54 @@ List userList service.getUsernameList(); Besides bean definitions that contain information on how to create a - specific bean, certain BeanFactory + specific bean, The ApplicationContext implementations also permit the registration of existing objects that are - created outside the factory, by users. The - DefaultListableBeanFactory class supports this - registration through the registerSingleton(..) - method. However, typical applications work solely with beans defined - through metadata bean definitions. + created outside the container, by users. This is done by accessing the + ApplicationContext's BeanFactory via the method + getBeanFactory which returns the BeanFactory + implementation DefaultListableBeanFactory. + DefaultListableBeanFactory supports this + registration through the methods + registerSingleton(..) and + registerBeanDefinition(..). However, typical + applications work solely with beans defined through metadata bean + definitions. For more information on the relationship between a + BeanFactory and the + ApplicationContext see .
Naming beans + Every bean has one or more identifiers. These identifiers must be + unique within the container that hosts the bean. A bean usually has only + one identifier, but if it requires more than one, the extra ones can be + considered aliases. + + When using XML-based configuration metadata, you use the + id and/or name attributes to + specify the bean identifier(s). The id attribute + allows you to specify exactly one id, and because it is a real XML + element ID attribute, the XML parser can do some extra validation when + other elements reference the id. As such, it is the preferred way to + specify a bean identifier. However, the XML specification does limit the + characters that are legal in XML ids. This is usually not a constraint, + but if you need to use one of these special XML characters, or want to + introduce other aliases to the bean, you can also specify them in the + name attribute, separated by a comma + (,), semicolon (;), or white + space. + + You are not required to specify a name or id for a bean. If no + name or id is supplied explicitly, the container generates a unique name + for that bean. However, if you want to refer to that bean by name, + through the use of the ref element or Service Location style lookup in + the ApplicationContext, you must provide a name. Motivations for not + supplying a name are related to using inner beans and autowiring collaborators. + Bean naming conventions @@ -531,31 +569,6 @@ List userList service.getUsernameList(); when applying advice to a set of beans related by name. - Every bean has one or more identifiers. These identifiers must be - unique within the container that hosts the bean. A bean usually has only - one identifier, but if it requires more than one, the extra ones can be - considered aliases. - - When using XML-based configuration metadata, you use the - id and/or name attributes to - specify the bean identifier(s). The id attribute - allows you to specify exactly one id, and because it is a real XML - element ID attribute, the XML parser can do some extra validation when - other elements reference the id. As such, it is the preferred way to - specify a bean identifier. However, the XML specification does limit the - characters that are legal in XML ids. This is usually not a constraint, - but if you need to use one of these special XML characters, or want to - introduce other aliases to the bean, you can also or instead specify - them in the name attribute, separated by a comma - (,), semicolon (;), or white - space. - - You are not required to supply a name for a bean. If no name is - supplied explicitly, the container generates a unique name for that - bean. The motivations for not supplying a name for a bean will be - discussed later (one use case is inner - beans). -
Aliasing a bean outside the bean definition @@ -570,9 +583,11 @@ List userList service.getUsernameList(); Specifying all aliases where the bean is actually defined is not always adequate, however. It is sometimes desirable to introduce an - alias for a bean that is defined elsewhere. In XML-based configuration - metadata, you can use of the <alias/> element - to accomplish this. + alias for a bean that is defined elsewhere. This is commonly the case + in large systems where configuration is split amongst each subsystem, + each subsystem having its own set of object defintions. In XML-based + configuration metadata, you can use of the + <alias/> element to accomplish this. <alias name="fromName" alias="toName"/> @@ -580,16 +595,17 @@ List userList service.getUsernameList(); 'fromName', may also after the use of this alias definition, be referred to as 'toName'. - For example, component A defines a DataSource bean called - componentA-dataSource, in its XML fragment. Component B refers to the - DataSource as componentB-dataSource in its XML fragment. The main - application, MyApp, defines its own XML fragment, assembles the final - application context from all three fragments, refers to the DataSource - as myApp-dataSource. To accomplish this scenario, you add to the MyApp - XML fragment the following standalone aliases: + For example, the configuration metadata for subsystem A may + refer to a DataSource via the name 'subsystemA-dataSource. The + configuration metadata for subsystem B may refer to a DataSource via + the name 'subsystemB-dataSource'. When composing the main application + that uses both these subsystems the main application refers to the + DattaSource via the name 'myApp-dataSource'. To have all three names + refer to the same object you add to the MyApp configuration metadata + the following aliases definitions: - <alias name="componentA-dataSource" alias="componentB-dataSource"/> -<alias name="componentA-dataSource" alias="myApp-dataSource" /> + <alias name="subsystemA-dataSource" alias="subsystemB-dataSource"/> +<alias name="subsystemA-dataSource" alias="myApp-dataSource" /> Now each component and the main application can refer to the dataSource through a name that is unique and guaranteed not to clash @@ -601,27 +617,6 @@ List userList service.getUsernameList();
Instantiating beans - - Inner class names - - If you want to configure a bean definition for a - static inner class, you have to use the - binary name of the inner class. - - For example, if you have a class called - Foo in the com.example - package, and this Foo class has a - static inner class called - Bar, the value of the - 'class' attribute on a bean definition would - be... - - com.example.Foo$Bar - - Notice the use of the $ character in the name - to separate the inner class name from the outer class name. - - A bean definition essentially is a recipe for creating one or more objects. The container looks at the recipe for a named bean when asked, and uses the configuration metadata encapsulated by that bean definition @@ -657,6 +652,27 @@ List userList service.getUsernameList(); + + Inner class names + + If you want to configure a bean definition for a + static inner class, you have to use the + binary name of the inner class. + + For example, if you have a class called + Foo in the com.example + package, and this Foo class has a + static inner class called + Bar, the value of the + 'class' attribute on a bean definition would + be... + + com.example.Foo$Bar + + Notice the use of the $ character in the name + to separate the inner class name from the outer class name. + +
Instantiation using a constructor @@ -730,7 +746,7 @@ List userList service.getUsernameList(); Similar to instantiation through a static factory method, instantiation with an instance factory method involves - the invocation of a non-static method of an existing bean from the + the invocation on a non-static method of an existing bean from the container to create a new bean. To use this mechanism, leave the class attribute empty, and in the factory-bean attribute, specify the name of a bean @@ -800,7 +816,12 @@ List userList service.getUsernameList(); Code is cleaner with the DI principle and decoupling is more effective when objects are provided with their dependencies. The object does not look up its dependencies, and does not know the location or - class of the dependencies. DI exists in two major variants, + + DI exists in two major variants, Constructor-based dependency injection and Setter-based dependency injection. @@ -808,15 +829,17 @@ List userList service.getUsernameList();
Constructor-based dependency injection - You accomplish constructor-based DI by - invoking a constructor with a number of arguments, each representing a - dependency. Calling a static factory method with - specific arguments to construct the bean is nearly equivalent, and - this discussion treats arguments to a constructor and to a - static factory method similarly. The following + Constructor-based DI is accomplished by the + container invoking a constructor with a number of arguments, each + representing a dependency. Calling a static factory + method with specific arguments to construct the bean is nearly + equivalent, and this discussion treats arguments to a constructor and + to a static factory method similarly. The following example shows a class that can only be dependency-injected by using constructor injection. Notice that there is nothing - special about this class. + special about this class, it is a POJO that has + no dependencies on container specific interfaces, base classes or + annotations. public class SimpleMovieLister { @@ -855,17 +878,18 @@ public class Foo { Bar and Baz classes are not related by inheritance. Thus the following configuration works fine, and you do not need to specify the constructor argument - indexes and/or types explicitly. + indexes and/or types explicitly in the + <constructor-arg/> element. <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 id="foo" class="x.y.Foo"> + <constructor-arg ref="bar"/> + <constructor-arg ref="baz"/> </bean> + + <bean id="bar" class="x.y.Bar"/> + <bean id="baz class="x.y.Baz"/> + </beans> When another bean is referenced, the type is known, and @@ -894,10 +918,10 @@ public class ExampleBean {
Constructor argument type matching - In the preceding scenario, you can use - type matching with simple types by explicitly specifying the type - of the constructor argument using the 'type' - attribute. For example: + In the preceding scenario, the container + can use type matching with simple types if + you explicitly specify the type of the constructor argument using + the 'type' attribute. For example: <bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg type="int" value="7500000"/> @@ -928,14 +952,20 @@ public class ExampleBean {
Setter-based dependency injection - You implement setter-based DI by calling - setter methods on your beans after invoking a no-argument constructor - or no-argument static factory method to instantiate - your bean. + Setter-based DI is accomplished by the + container calling setter methods on your beans after invoking a + no-argument constructor or no-argument static + factory method to instantiate your bean. + + The ApplicationContext supports + constructor- and setter-based DI for the beans it manages. It also + supports setter-based DI after some dependencies are already injected + through the constructor approach. The following example shows a class that can only be dependency-injected using pure setter injection. This class is - conventional Java. + conventional Java. It is a POJO that has no dependencies on container + specific interfaces, base classes or annotations. public class SimpleMovieLister { @@ -953,6 +983,13 @@ public class ExampleBean { Constructor-based or setter-based DI? + Since you can mix both, Constructor- and Setter-based DI, it + is a good rule of thumb to use constructor arguments for mandatory + dependencies and setters for optional dependencies. Note that the + use of a @Required + annotation on a setter can be used to make setters required + dependencies. + The Spring team generally advocates setter injection, because large numbers of constructor arguments can get unwieldy, especially when properties are optional. Setter methods also make objects of @@ -972,33 +1009,24 @@ public class ExampleBean { expose any setter methods, and so constructor injection is the only available DI. +
- The ApplicationContext supports - constructor- and setter-based DI for the beans it manages. It also - supports setter-based DI after some dependencies are already injected - through the constructor approach. You configure the dependencies in - the form of a BeanDefinition, which you - use with PropertyEditor instances to - convert properties from one format to another. However, most Spring - users do not work with these classes directly (programmatically), but - rather with an XML definition file that is then converted internally - into instances of these classes, and used to load an entire Spring IoC - container instance. +
+ Dependency resolution process - In general, you resolve bean dependency as follows: + The container performs bean dependency resolution as + follows: - Create the ApplicationContext - and initialize it with a configuration that describes all the - beans. (Many Spring users prefer an - ApplicationContext implementation - that supports XML format configuration files, but Java code and - annotation-based configurations are also supported.) + The ApplicationContext is + created an initialized with configuration metadata that describes + all the beans. Configuration metadata can be specified via XML, + Java code or annotations. - For each bean, create dependencies in the form of + For each bean, its dependencies are expressed in the form of properties, constructor arguments, or arguments to the static-factory method if you are using that instead of a normal constructor. These dependencies are provided to the bean, @@ -1006,18 +1034,17 @@ public class ExampleBean { - Make each property or constructor argument an actual - definition of the value to set, or a reference to another bean in - the container. + Each property or constructor argument an actual definition + of the value to set, or a reference to another bean in the + container. - - Make sure that each property or constructor argument that is a - value can be converted from its specified format to the actual - type of that property or constructor argument. By default Spring - can convert a value supplied in string format to all built-in - types, such as int, long, + Each property or constructor argument which is a value is + converted from its specified format to the actual type of that + property or constructor argument. By default Spring can convert a + value supplied in string format to all built-in types, such as + int, long, String, boolean, etc. @@ -1027,10 +1054,10 @@ public class ExampleBean { reference properties refer to valid beans. However, the bean properties themselves are not set until the bean is actually created. Beans that are singleton-scoped and set to be - pre-instantiated (such as singleton beans in an - ApplicationContext) are created when - the container is created. Otherwise, the bean is created only when it - is requested. Creation of a bean potentially causes a hierarchy of + pre-instantiated (the default) are created when the container is + created. Scopes are defined in the section Otherwise, the bean is created only + when it is requested. Creation of a bean potentially causes a graph of beans to be created, as the bean's dependencies and its dependencies' dependencies (and so on) are created and assigned. @@ -1044,7 +1071,7 @@ public class ExampleBean { constructor injection, and class B equires an instance of class A through constructor injection. If you configure beans for classes A and B to be injected into each other, the Spring IoC container - detect st this circular reference at runtime, and throws a + detects this circular reference at runtime, and throws a BeanCurrentlyInCreationException. One possible solution is to edit the source code of some @@ -1063,11 +1090,12 @@ public class ExampleBean { configuration problems, such as references to non-existent beans and circular dependencies, at container load-time. Spring sets properties and resolves dependencies as late as possible, when the bean is - actually created. A Spring container that loads correctly can generate - an exception when there is a problem creating a requested bean or one - of its dependencies. For example, the bean throws an exception as a - result of a missing or invalid property. This potentially delayed - visibility of some configuration issues is why + actually created. This means that a Spring container which has loaded + correctly can later generate an exception when you request an object + if there is a problem creating that object or one of its dependencies. + For example, the bean throws an exception as a result of a missing or + invalid property. This potentially delayed visibility of some + configuration issues is why ApplicationContext implementations by default pre-instantiate singleton beans. At the cost of some upfront time and memory to create these beans before they are actually needed, @@ -1268,7 +1296,7 @@ public class ExampleBean { - The preceding XML is more succinct; however, typos are + The preceding XML is more succinct; however, typos are discovered at runtime rather than design time, unless you use an IDE such as IntelliJ IDEA or the The idref element The idref element is simply an error-proof - way to pass the id of another bean in the - container to a <constructor-arg/> or + way to pass the id ((string value - not a + reference)of another bean in the container to a + <constructor-arg/> or <property/> element. <bean id="theTargetBean" class="..."/> @@ -1504,12 +1533,6 @@ public class ExampleBean { </property> </bean> - - The nested element style shown in the preceding example - becomes verbose. Fortunately, attribute shortcuts exist for most - elements; see . - - The value of a map key or value, or a set value, can also again be any of the following elements: @@ -1686,89 +1709,8 @@ support=support@example.co.uk code: exampleBean.setEmail(null).
-
- XML shortcut with configuration metadata - - Several options can limit the amount of XML you have to write to - configure your components. The first is a shortcut to define values - and references to other beans as part of a - <property/> definition. The - <property/>, - <constructor-arg/>, and - <entry/> elements all support a - 'value' attribute that you can use instead of - embedding a full <value/> element. Therefore, - the following: - - <property name="myProperty"> - <value>hello</value> -</property> - - <constructor-arg> - <value>hello</value> -</constructor-arg> - - <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 similar - shortcut 'ref' attribute that you can use 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"/> - - However, the shortcut form is equivalent to a <ref - bean="xxx"> element; no shortcut exists for - <ref local="xxx">. To enforce a strict local - reference, you must use the long form. - - Finally, the entry element allows a shortcut form to specify the - key and/or value of the map, in the form of the - 'key' / 'key-ref' and - '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 - <ref local="xxx">. -
-
- XML shortcut with the p-namespace + XML shortcut with the p-namespace You can also decrease the amount of required XML by using the "p-namespace". Spring 2.0 and later features support for extensible @@ -6654,7 +6596,7 @@ cfg.postProcessBeanFactory(factory); and AOP are implemented.
-
+
Glue code and the evil singleton The majority of the code inside an application is best written in