IO /spring-fram…

1.3 summary of Bean

The Spring IoC container manages one or more beans. These beans are created using configuration metadata that you provide (for example, defined in XML).

Within the container itself, these bean definitions are represented as BeanDefinition objects, which contain (among other information) the following metadata:

  • Fully qualified name of the class: Usually the actual implementation class of the defined bean
  • The Bean behavior configures the element, declaring that the Bean should behave in the container (scope, lifecycle callbacks, and so on).
  • References to other necessary beans: These references are also called dependencies
  • Object configuration values: for example, the size limit of the pool or the number of connections to use to manage the pool of connections.

Metadata is transformed into properties defined by each bean. The following table describes these attributes:

Property Explained in…
Class Instantiating Beans
Name Naming Beans
Scope Bean Scopes
Constructor arguments Dependency Injection
Properties Dependency Injection
Autowiring mode Autowiring Collaborators
Lazy initialization mode Lazy-initialized Beans
Initialization method Initialization Callbacks
Destruction method Destruction Callbacks

In addition to bean definitions that contain information about how a particular bean is created, the ApplicationContext implementation also allows you to register existing objects that are created (by the user) outside the container. Through getBeanFactory () method to access the ApplicationContext the BeanFactory to complete, this method returns the BeanFactory DefaultListableBeanFactory implementation class. DefaultListableBeanFactory through registerSingleton (..) And registerBeanDefinition (..) Method supports registration. However, a typical application uses only regular metadata to define beans.

Bean metadata and hand-supplied singleton instances need to be registered early so that the container can properly reason about them in the autowiring and other introspection steps. While overwriting existing metadata and existing singleton instances is supported to some extent, registering new beans at run time (in conjunction with live access to the factory) is not officially supported and can result in concurrent access exceptions and inconsistent state in the bean container.

1.3.1 Naming of beans

Each bean has one or more identifiers. These identifiers must be unique in the bean’s container. A bean usually has only one identifier. However, if more than one is required, the additional identifiers can be treated as aliases

In XML-based configuration metadata, bean identifiers can be specified using the ID attribute, the name attribute, or both. The ID attribute allows you to specify an ID. Typically, these names are alphanumeric (‘myBean’, ‘someService’, etc.), but they can also contain special characters. If you want to introduce additional aliases for beans, you can also specify them in the name attribute, using ‘,’,’; ‘or space delimited. Prior to Spring 3.1, the ID attribute was defined as type XSD: ID, which limited the possible characters. Since 3.1, it has been defined as XSD: String. Bean ID uniqueness is enforced by the container, not by the XML parser.

It is not necessary to provide a name or ID for the bean. If you do not explicitly provide a name or ID, the container will generate a unique name for the bean. However, if you want to reference the bean by name by using the REF element or the Service Locator style, you must provide the name. Do not provide named motives with using inner beans and Autowiring properties. The relevant.

The convention is to use standard Java conventions when naming beans. That is, bean names start with a lowercase letter and use camel name. For example, accountManager, accountService, userDao, and loginController.

Naming beans consistently makes your configuration easier to read and understand. In addition, if you use Spring AOP, it can be very helpful when applying advice to a set of beans related to their names.

By scanning components in the classpath, Spring generates bean names for unnamed components, following the rules described earlier: essentially, it takes a simple class name and converts its initial characters to lowercase. However, in (uncommon) special cases where there are multiple characters and the first and second characters are both uppercase, the original case is retained. . These rules and Java beans. Introspector. Decapitalize here (Spring) used to define the rules of the same.

Alias the Bean outside of the Bean definition

In the bean definition itself, you can provide a bean with multiple names that are equivalent aliases for the bean by specifying at most one name with a unique ID and by using the name attribute that can specify any value.

However, it is not always appropriate to specify all aliases at bean definition time, and sometimes you need to introduce aliases for beans defined elsewhere. In large systems, configuration is split between each subsystem, each with its own set of object definitions. In XML-based configuration metadata, you can use elements to do this. The following example shows how to do this:

<alias name="fromName" alias="toName"/>
Copy the code

In this case, the bean named fromName (in the same container) could also be called toName after using the alias definition.

For example, the configuration metadata for subsystemA refers to A dataSource by the name subsystema-datasource. The configuration metadata for subsystemB refers to a dataSource by the name of subsystemb-datasource. When the two subsystems are combined, the main application refers to the dataSource by the name myapp-datasource. To have all three names refer to the same object, add the following alias definition to the configuration metadata:

<alias name="myApp-dataSource" alias="subsystemA-dataSource"/>
<alias name="myApp-dataSource" alias="subsystemB-dataSource"/>
Copy the code

Now, both the subsystem and the main application can refer to the dataSource by a unique name that is guaranteed not to conflict with any other definition, but they refer to the same bean.

If you use Java Configuration, you can provide aliases using @Bean annotations. For more information, see Using @bean Annotations.

1.3.2 Instantiating beans

A Bean definition is essentially a method for creating one or more objects. The container looks at the named bean definition to create (or get) the actual object when asked.

If you use XML-based configuration metadata, you need to specify the class type of the instantiated object to be specified in the element’s class attribute. This property, which internally is a class property on a BeanDefinition instance, is usually mandatory (for exceptions, see object instantiation using Instance Factory methods and Bean definition inheritance). You can use the Class attribute in one of two ways:

  • Typically, specifying the bean class to be constructed is somewhat equivalent to Java code with the new operator, in the case that the container itself creates the bean directly by calling the constructor through reflection.

  • It is not often that the container calls the static factory method on the class to create the bean, specifying the actual class that contains the static factory method used to create the object. The object type returned by calling a static factory method can be the same class as the factory class or another class.

If you want to configure the bean definition for the inner class, you can use the binary or source name of the inner class.

For example, if you have a class called SomeThing in com.example. The SomeThing class has a static inner class called OtherThing, which can use either a dollar sign () or a dot (.) Space. Therefore, the value of the class property in the bean definition should be com.example.something) or dot (.). Space. Therefore, the value of the class property in the bean definition should be com.example.something) or dot (.). Space. So the class attribute value in the bean definition should be com. Example. SomeThingOtherThing or com. Example. SomeThing. OtherThing.

Instantiate beans through constructors

When you create a bean through the constructor method, all the normal classes are available to Spring and are spring-compatible. That is, classes hosted for Spring don’t need to implement any particular interface or be coded in a particular way, just specify the bean class name. However, a default (empty) constructor is required.

The Spring IoC container can manage virtually any class you want it to manage. It is not limited to managing real Javabeans. Most Spring users prefer to have default (no-argument) constructors and Javabean classes with setters and getters based on properties in the container. You can also add more non-Javabean-style classes to the container. For example, if you need to use connection pooling that is absolutely non-compliant with the JavaBean specification, Spring can manage that as well.

Using XML-based configuration metadata, you can specify your bean class as follows:

<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
Copy the code

For more information about the mechanism for providing parameters to constructors and setting object instance properties after object construction, see dependency injection

The bean is instantiated through the static factory method

When defining a bean created using a static factory method, use the class attribute to specify the class containing the static factory method, and use an attribute named factory-method to specify the name of the factory method itself. You should be able to call this method (with optional arguments) to return an active object, which is then considered to have been created through the constructor.

The following bean definition specifies that the bean is created by calling a factory method. This definition does not specify the type (class) of the returned object, only the class that contains the factory method. In this example, the createInstance() method must be a static method. The following example shows how to specify a factory method:

<bean id="clientService"  
class="examples.ClientService" 
factory-method="createInstance"/>
Copy the code

The following example shows a class that can be defined using the previous bean:

public class ClientService { private static ClientService clientService = new ClientService(); private ClientService() {} public static ClientService createInstance() { return clientService; }}Copy the code

For more information about the mechanism for providing (optional) parameters to factory methods and setting object instance properties after returning an object from the factory, refer to Dependencies and Configuration Details docs.

Instantiation is done through the instance factory method

Similar to instantiation through a static factory method, instantiation of an instance factory method is used to create a new bean by calling a non-static method of an existing bean from the container. To use this mechanism, leave the class attribute empty and, in the factory-bean attribute, specify the name of the bean in the current (or parent or ancestor) container that contains the instance method to be called to create the object. Use the factory-method property to set the name of the factory method itself. The following example shows how to configure such a bean:

<! -- the factory bean, which contains a method called createInstance() --> <bean id="serviceLocator" class="examples.DefaultServiceLocator"> <! -- inject any dependencies required by this locator bean --> </bean> <! -- the bean to be created via the factory bean --> <bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/>Copy the code

The following example shows the corresponding class:

public class DefaultServiceLocator { private static ClientService clientService = new ClientServiceImpl(); public ClientService createClientServiceInstance() { return clientService; }}Copy the code

A factory class can also contain multiple factory methods, as shown in the following example:

<bean id="serviceLocator" class="examples.DefaultServiceLocator"> <! -- inject any dependencies required by this locator bean --> </bean> <bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/> <bean id="accountService" factory-bean="serviceLocator" factory-method="createAccountServiceInstance"/>Copy the code

The following example shows the corresponding class:

public class DefaultServiceLocator { private static ClientService clientService = new ClientServiceImpl(); private static AccountService accountService = new AccountServiceImpl(); public ClientService createClientServiceInstance() { return clientService; } public AccountService createAccountServiceInstance() { return accountService; }}Copy the code

In Spring documentation, “Factory bean” refers to the creation of an object in the Spring container through an instance or static factory method. In contrast, a FactoryBean(note the uppercase) refers to the FactoryBean implementation class.

Determine the runtime type of the Bean

It is important to determine the runtime type of a particular bean. The specified class in the bean metadata definition is just an initial class reference that may be instantiated using static factory methods or instance factory methods, which may result in a different runtime type of bean. In addition, an AOP proxy can wrap a bean instance with an interface-based proxy, with limited exposure to the actual type of the target bean (just the interface implemented).

To understand the actual runtime type of a particular bean, it is recommended to specify bean name retrieval using the getType method of the BeanFactory.