zoukankan      html  css  js  c++  java
  • Spring 构造注入!

    3.3.1. Injecting dependencies

    The basic principle behind Dependency Injection (DI) is that objects define their dependencies (that is to say the other objects they work with) only through constructor arguments, arguments to a factory method, or properties which are set on the object instance after it has been constructed or returned from a factory method. Then, it is the job of the container to actually inject those dependencies when it creates the bean. This is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself being in control of instantiating or locating its dependencies on its own using direct construction of classes, or something like the Service Locator pattern.

    It becomes evident upon usage that code gets much cleaner when the DI principle is applied, and reaching a higher grade of decoupling is much easier when objects do not look up their dependencies, but are provided with them (and additionally do not even know where the dependencies are located and of what concrete class they are). DI exists in two major variants, namely Constructor Injection and Setter Injection.

    3.3.1.1. Constructor Injection

    Constructor-based DI is effected by invoking a constructor with a number of arguments, each representing a dependency. Additionally, calling a static factory method with specific arguments to construct the bean, can be considered almost equivalent, and the rest of this text will consider arguments to a constructor and arguments to a static factory method similarly. Find below an example of a class that could only be dependency injected using constructor injection. Notice that there is nothing special about this class.

    public class SimpleMovieLister {
    
        // the SimpleMovieLister has a dependency on a MovieFinder
        private MovieFinder movieFinder;
    
        // a constructor so that the Spring container can 'inject' a MovieFinder
        public SimpleMovieLister(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }
        
        // business logic that actually 'uses' the injected MovieFinder is omitted...
    }
    3.3.1.1.1. Constructor Argument Resolution

    Constructor argument resolution matching occurs using the argument's type. If there is no potential for ambiguity in the constructor arguments of a bean definition, then the order in which the constructor arguments are defined in a bean definition is the order in which those arguments will be supplied to the appropriate constructor when it is being instantiated. Consider the following class:

    package x.y;
    
    public class Foo {
    
        public Foo(Bar bar, Baz baz) {
            // ...
        }
    }

    There is no potential for ambiguity here (assuming of course that Bar and Baz classes are not related in an inheritance hierarchy). Thus the following configuration will work just fine, and you do not need to 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). When a simple type is used, such as <value>true<value>, Spring cannot determine the type of the value, and so cannot match by type without help. Consider the following class:

    package examples;
    
    public class ExampleBean {
    
        // No. of years to the calculate the Ultimate Answer
        private int years;
    
        // The Answer to Life, the Universe, and Everything
        private String ultimateAnswer;
    
        public ExampleBean(int years, String ultimateAnswer) {
            this.years = years;
            this.ultimateAnswer = ultimateAnswer;
        }
    }
    3.3.1.1.1.1. Constructor Argument Type Matching

    The above scenario can use type matching with simple types by explicitly specifying the type of 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>
    3.3.1.1.1.2. Constructor Argument Index

    Constructor arguments can have their index specified 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 where a constructor may have two arguments of the same type. Note that the index is 0 based.

  • 相关阅读:
    Part 11 Search filter in AngularJS
    Part 10 AngularJS sort rows by table header
    Part 9 Sorting data in AngularJS
    Part 8 AngularJS filters
    Part 7Handling events in AngularJS
    Part 6 AngularJS ng repeat directive
    PHP单一入口应用程序概述
    SVN
    跨平台的.NET集成开发环境:MonoDevelop
    PHP中使用KindEditor
  • 原文地址:https://www.cnblogs.com/yangzhi/p/3576541.html
Copyright © 2011-2022 走看看