Spring Core Technology IOC container (iv)

Source: Internet
Author: User

The previous two articles describe the concepts of dependency in the IOC container, including dependency injection and injection detail configuration. This article will continue to describe all dependent information for playing.

Using depends-on

If a bean is dependent on another bean, this bean is usually one of the attributes of another bean. In most cases, developers can use tags when configuring XML metadata <ref/> . However, sometimes the dependencies between the beans are not directly related. For example, you need to invoke the static instantiation of the class to start, similar to database-driven registration. depends-onproperty causes explicit forced-dependent beans to be initialized before they are referenced. The following example uses depends-on attributes to let you represent a dependency on a singleton bean.

id="beanOne"class="ExampleBean" depends-on="manager"id="manager"class="ManagerBean" />

If you want to rely on multiple beans, you can provide multiple names as values for depends-on , separated by commas, spaces, or semicolons, as follows:

<bean id  = "Beanone"  class  = " Examplebean " depends-on   = "Manager,accountdao"  > <property  name  =" manager " ref  =< Span class= "hljs-string" > "manager" /></bean><bean id  = "manager"  class  = " Managerbean "/><bean id  =" Accountdao "  class  = "X.y.jdbc.jdbcaccountdao" /> 

The attributes in the bean depends-on can specify both a dependency on the initialization time and a corresponding destroy-time dependency (singleton Bean case). Independently defined depends-on attributes of the bean will be preferentially destroyed, better than depends-on the bean to destroy, which depends-on can control the order of destruction.

Deferred-initialized Bean

By default, ApplicationContext all singleton beans are created and configured during instantiation. In general, this pre-initialization is very good. Because some of the configuration errors in the environment can be discovered in time, not after the system has been running for a long time. If this behavior is not urgently needed, developers can block this pre-initialization by marking the bean as lazy loading. A deferred-initialized Bean notifies the IOC not to initialize the bean but to instantiate it when it is referenced.
In XML, <bean/> This behavior can be controlled through the attributes of the element lazy-init . As follows:

id="lazy"class="com.foo.ExpensiveToCreateBean" lazy-init="true"name="not.lazy"class="com.foo.AnotherBean"/>

When the bean is configured as the XML above, the bean in it ApplicationContext lazy does not ApplicationContext enter the pre-initialized state with the boot, and those non-lazy loaded beans are in pre-initialized state.

However, if a deferred-loading class exists as a dependency of a singleton non-lazy loaded bean, it ApplicationContxt will still be loaded at ApplicationContext startup, because the dependency as a singleton bean is instantiated with the singleton bean instantiation.
Developers can <beans/> default-lazy-init then control whether the bean is deferred for initialization by using the properties of the container hierarchy, such as:

<beans default-lazy-init="true">    <!-- no beans will be pre-instantiated... --></beans>
Automatic Assembly Association

The spring container can automatically assemble dependencies between the associated beans. Developers can make spring ApplicationContext parse these associations by moving them. The automatic loading has a lot of a bit:

    • Automatic loading can significantly reduce the specified attributes or construct parameters.
    • Automatic loading can extend the developer's object. For example, if a developer needs to add a dependency, the dependency can be automatically met without the developer being particularly concerned about changing the configuration. In this way, automatic loading is extremely useful in the development process, without the explicit selection of load dependencies that will make the system more stable.

When using XML-based metadata configuration, developers can specify how to assemble automatically. <bean/>You can do this by configuring the properties of the element autowire . There are four ways to automate loading, and developers can specify how each bean is to be loaded so that the bean knows how to load its dependencies.

mode explanation
no (default) does not load. A reference to a bean must be specified by the ref element. For larger project deployments, it is not recommended to modify the default configuration, as specifically it will aggravate the control. In a way, the default form also illustrates the structure of the system.
byname is assembled by name. Spring will look for all beans that know the same name and attribute of the same bean to be loaded. For example, if the bean is configured to automatically assemble by name, it contains a property named Master (that is, it contains a setmaster (..) method), spring looks for the bean with the name master and then loads it with
bytype If the type of the property that you want to automatically assemble exists in the container, will be assembled automatically. If there is more than one type match in the container, a significant exception is thrown, stating that the developer should not use Bytype to assemble the bean. If no matching bean exists, no exception is thrown, except that the property is not configured. The
constructor is similar to the injection of Bytype , but the parameters of the constructor are applied. If no bean type and constructor arguments are the same type, then a significant exception is thrown

Through the automatic assembly of Bytype or constructors , developers can be loaded into arrays and strongly typed collections. In such an example, the bean matching the specified type in all the containers is automatically assembled to the bean to complete the dependency injection. Developers can automatically assemble a String strong type of key Map . The automatically assembled Map values will contain all bean instance values to match the specified type, and Map the key will contain the name of the associated bean.

Limitations and disadvantages of automatic assembly

Automatic equipment will work well if it is used throughout the development of the project. But if you're not using it globally, and you're using it to automatically assemble a few beans, it's confusing for developers.

Here are some of the disadvantages and limitations of automatic assembly

    • Precise property and constructor-arg parametric configurations override the automatic assembly configuration. Development is not able to automatically assemble so-called simple attributes, such as primitive types or strings.
    • Automatic assembly and accurate assembly. Although spring will try to avoid unnecessary error assembly as described in the table above, spring managed object relationships are still less accurate than the documentation describes.
    • Assembled information is not visible to developers because it is managed by the spring container.
    • There may be many bean matching setter methods or construction parameters in the container. For example, arrays, sets, or maps. However, relying on the hope that only a matching value, vague information is unresolved. If there is no unique bean, then an exception is thrown.

In the back of the scene, developers have a choice

    • Waiver of automatic assembly facilitates precise assembly
    • You can autowire-candidate false prevent automatic assembly by configuring properties for
    • <bean/> primary true Specify a bean as the primary candidate bean by configuring the attribute of the element
    • Implement more annotation-based, fine-grained assembly configurations.
Exclude a bean so that it does not assemble automatically

On the basis of each bean, the developer can block the bean from moving the assembly. In an XML-based configuration, you can configure the <bean/> attributes of an element autowire-candidate to false do this. When the container is read to this configuration, it makes the bean invisible to the structure of the automatic assembly (including the configuration of annotations, for example @Autowired )

Developers can limit the candidates for automatic assembly by pattern matching rather than by the name of the bean. The topmost <beans/> element default-autowire-candidates configures multiple schemas in the attribute. For example, restricting the names of candidates for automatic assembly ends with Repository and can be configured *Repository . If you need to configure multiple modes, just separate them with commas. Of course, if configured in the Bean autowire-candidate , this information has a higher priority.

The above techniques are very effective in configuring beans that do not require automatic assembly. This is not to say that the bean itself cannot automatically assemble the other beans, but that the beans are not candidates for automatic assembly dependencies.

Method injection

Most of the beans are singleton in most scenarios. When this singleton bean needs to be used in conjunction with another singleton or non-singleton bean, the developer only needs to configure the dependent bean as the bean's property. But sometimes problems arise because of different bean life cycles. Suppose Bean A in the singleton uses a non-singleton bean B in each method invocation. The container only creates bean a once, and there is only one chance to configure the property. Then the container will not be able to give Bean a a new instance of Bean B each time.

One solution is to abandon some IOC. A developer can ApplicationContextAware see the Bean A by implementing an interface ApplicationContext , which is called to fetch a new instance of getBean("B") B when bean a needs new instances. Refer to the following example:

//A class that uses a stateful Command-style class to perform some processing PackageFiona.apple;//Spring-api ImportsImportOrg.springframework.beans.BeansException;ImportOrg.springframework.context.ApplicationContext;ImportOrg.springframework.context.ApplicationContextAware; Public  class Commandmanager implements applicationcontextaware {    PrivateApplicationContext ApplicationContext; PublicObjectProcess(Map commandstate) {//Grab a new instance of the appropriate CommandCommand command = CreateCommand ();//Set the state on the (hopefully brand new) Command instanceCommand.setstate (commandstate);returnCommand.Execute (); }protectedCommandCreateCommand() {//Notice the Spring API dependency!        return  This. Applicationcontext.getbean ("command", Command.class); } Public void Setapplicationcontext(ApplicationContext ApplicationContext)throwsbeansexception { This. ApplicationContext = ApplicationContext; }}

The code above is not very satisfying, as the code for the business has been coupled with the spring framework. Spring provides a slightly advanced approach to point attribute method injection that can be used to handle this problem.

Find Method Injection

Find method injection is the ability of a container to override the container management bean to return the bean in another container that is being found. The lookup method usually contains the bean mentioned in the previous scenario. The spring framework uses the bytecode generated by the Cglib library to dynamically generate subclasses to override the method implementation method injection of the parent class.

  • In order for this dynamic subclass scheme to be normal, the parent class inherited by the spring container cannot be final , and the overridden method cannot be final .
  • Unit tests for this class because there is an abstract method, you must implement subclasses to test
  • The specific method required for component scanning also requires a specific class.
  • A key limitation is that the lookup method and the factory method do not work together, especially the methods that are not in the configuration class, @Bean because the container is not responsible for creating the instance, but rather creating a subclass of the runtime.
  • Finally, the injected object to the method cannot be serialized.

Seeing the class in the previous code snippet CommandManager , we found that the spring container would dynamically overwrite the createCommand() method. CommandManagerThe class does not have any spring dependencies, as follows:

package fiona.apple; No more Spring imports!  public  abstract  class  Commandmanager {public  object process  (object        Commandstate) {//grab a new instance of the appropriate Command interface         Command command = CreateCommand (); //set the state on the (hopefully brand new) Command instance  command.setstate (c        Ommandstate);    return  Command.Execute ();    } //okay ... but where was the implementation of this method?  protected  abstract  Command createcommand  ();}  

In the client class that contains the method that needs to be injected, the injected method needs to have the following function signature

<public|protected> [abstract] <returntheMethodName(no-arguments);

If the method is abstract, then dynamically generated subclasses implement this method. Otherwise, dynamically generated subclasses override the original method of the definition in the class. For example:

<!--A stateful bean deployed as a prototype (Non-singleton)--<bean id="command" class="Fiona.apple.AsyncCommand" scope ="Prototype">    <!--inject dependencies here as required--</Bean><!--Commandprocessor uses Statefulcommandhelper --<bean id="Commandmanager" class="Fiona.apple.CommandManager " >    <lookup-method name="CreateCommand" bean="command" /></Bean>

The above Commandmanager calls its own method createCommand() when it needs a new instance of the command bean. Developers must be careful to configure command beans for the prototype type of bean. If the required bean is singleton, then the method injected will return the same instance.

Arbitrary method substitution

From the previous description, we know that the lookup method is capable of overwriting any method of a container-managed bean. Developers should skip this section unless they need to use this feature.

By configuring XML-based configuration metadata, developers can use replaced-method elements to replace an implementation of an existing method. Consider the following scenario:

publicclass MyValueCalculator {    publiccomputeValue(String input) {        // some real code...    }    // some other methods...}

A org.springframework.beans.factory.support.MethodReplacer class that implements an interface provides a definition of a new method.

/** * meant to be used to override the existing computeValue(String) * implementation in MyValueCalculator */publicclass ReplacementComputeValue implements MethodReplacer {    publicreimplementthrows Throwable {        // get the input value, work with it, and return a computed result        String input = (String) args[0];        ...        return ...;    }}

If you need to overwrite the bean's method you need to configure the XML as follows:

<bean id="Myvaluecalculator" class="X.y.z.myvaluecalculator " >    <!--arbitrary method replacement --    <replaced-method name= "computevalue" replacer=" Replacementcomputevalue ">        <arg-type>String</arg-type>    </replaced-method></Bean><bean id= "replacementcomputevalue" class=" A.b.c.replacementcomputevalue "/>

Developers can use more of the <replaced-method> <arg=type/> elements in to specify the methods that need to be overwritten. Specifying a parameter is necessary when there are overloaded methods in the method that needs to be overridden. For convenience, the type of the string will match the following type, which is exactly equivalent to java.lang.String .

java.lang.StringStringStr

Because the number of parameters is usually enough to distinguish different methods, this shortcut can save a lot of code.

So far, the basic information about Dependency Injection in Spring core technology has been fully described, and the next blog post will cover the scope of the bean.

Spring Core Technology IOC container (iv)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.