韶光淑气_Spring_3.0 依赖注入_2020年4月10日11:57:43

依赖注入

  • 项目开发中,单个实例并不仅存在基本类型属性,亦或存在其他类型实例。Spring可对其进行初始化赋值,也被称为注入。此实例之创建,需其他实例作为属性方可,故称此示例依赖其他实例而存在,故构成依存关系。

  • 依赖注入如上文所说,一对象依赖某其他对象,则对此对象注入其他对象至引用中。被依赖只对象只可通过构造参数、工厂方法参数、或在对象set方法的途径赋值到依赖对象中。

  • 依赖注入称为DI,此类方式可使对象并为察觉所依赖对象位置或类型即可获取其实例,简化代码的同时耦合度响应降低,因注入的可能是属性的子类类型,故可能性较多的,但通过依赖注入可降低耦合度,灵活控制对象的创建。

  • DI主要借助构造方法注入与set方法注入。

构造方法注入

  • 通过构造方法注入要求类中存在公开有参构造,参数用于向对象类型属性赋值。

  • 构造方法中参数的匹配是通过类型进行的,即相应类型参数对相应类型属性。此实例由Spring创建,在xml文件中使用constructor-arg标签在bean中注入。如果构造函数参数类型相同,则标签的顺序即为赋值的顺序。

    package x.y;
    ​
    public class ThingOne {
        public ThingOne(ThingTwo thingTwo, ThingThree thingThree) {
            // 对参数的操作或赋值
        }
    }
    <beans>
        <bean id="beanOne" class="x.y.ThingOne">
            <constructor-arg ref="beanTwo"/>
            <constructor-arg ref="beanThree"/>
        </bean><bean id="beanTwo" class="x.y.ThingTwo"/><bean id="beanThree" class="x.y.ThingThree"/>
    </beans>
  • 还可通过类型指定的方式进行属性赋值,如true一字,可为String亦可为boolean,具体类型可在constructor-arg标签中借助type属性进行指定:

    <bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg type="int" value="7500000"/>
        <constructor-arg type="java.lang.String" value="42"/>
    </bean>
  • 若多个参数类型相同,还要进行指定参数的赋值,则需通过下标的方式进行设置,下标使用index属性指定,起始值为0:

    <bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg index="0" value="7500000"/>
        <constructor-arg index="1" value="42"/>
    </bean>
  • 还可通过使用name属性指定参数名称来进行设置:

    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
    <bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg name="years" value="7500000"/>
        <constructor-arg name="ultimateAnswer" value="42"/>
    </bean>

    使用参数名的方式配置,需开启debug模式运行程序,以便Spring获取构造函数,且在其中获取其名。如果要直接运行程序且使用参数名的方式,要在构造函数中使用ConstructorProperties注解指定参数名:

    @ConstructorProperties({"years", "ultimateAnswer"})
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }

Setter方法注入

  • 在进行注入时,若为强制性注入即必要此属性存在对象,则可使用构造函数注入方式。若为可选择方式,即可为空的属性注入,则使用setter方法注入。但可在set方法上添加@Required注解,将此set方法定为必要注入项。

  • Spring团队提倡构造函数注入,因为可确保对象实现不可变,并确保不存在必需的null内容。并且构造函数注入方式使创建的实例以完全初始化的状态进行调用。

  • 默认情况下,Spring可以将注入的String类型的值与其他基本类型进行转换然后注入。

  • 循环依赖问题要注意,例如A类中存在属性B,B类中存在属性A,然后将两个类之间相互进行注入则会发生循环注入问题,将出现BeanCurrentlyInCreationException。避免这种问题可使用setter方式注入,或者采用不同的构造函数进行循环依赖。

  • 在进行注入之前,会先将需要到的实例进行创建,然后再向属性中注入。

  • 在进行setter方法进行注入的时候,可在bean中添加property标签,其中可直接指定属性名称,将自动调用其set方法,必须保证其拥有响应set方法。value属性可对基本类型进行赋值,ref可借鉴其他bean标签所创建的实例进行注入。

    public class A {
        B b;
        int age;
    ​
        public void setB(B b) {
            this.b = b;
        }
    ​
        public void setAge(int age) {
            this.age = age;
        }
    }
    <bean id="createA" class="bean.A">
        <property name="b" ref="createB"></property>
        <property name="age" value="10"></property>
    </bean><bean class="bean.B" id="createB"></bean>
  • 还可将ref作为一个标签写在property标签之中,使用bean属性指定将注入的bean标签标识:

    <bean id="createA" class="bean.A">
        <property name="b">
            <ref bean="createB"></ref>
        </property>
        <property name="age" value="10"></property>
    </bean><bean class="bean.B" id="createB"></bean>

猜你喜欢

转载自www.cnblogs.com/agoodjavaboy/p/12672530.html