• Spring备忘四(涵盖Spring2.5)


    依赖注入(IOC DI)

    依赖注入的两种方式:

    1. set注入

    Spring要求使用set注入方式的时候,Bean需要提供一个无参数的构造方法。并提供一个属性的setter方法。例如:

    package com.kay.bean;

    public class UserServices {

    private UserBean ub;

    public void setUb(UserBean ub) {

    this.ub = ub;

    }

    public void add(){

    ub.add();

    }

    }

    在上面的例子中UserServices类依赖与UserBean类,那么可以在配置文件中进行配置。

    配置方法1:

    <!-- 将userBean交给spring管理 -->

    <bean id="userBean" class="com.kay.bean.UserBean"/>

    <!-- 将userServics交给spring管理 -->

    <bean id="userServices" class="com.kay.bean.UserServices">

    <!-- 利用propterty节点进行setter方法的注入 -->

    <property name="ub"><ref bean="userBean"/></property>

    </bean>

    在配置文件中preperty节点中的name属性指的是UserServices类中的set方法的名字,比如setXXX,和属性名字无关。ref节点的bean属性指的是要引用的一个Bean,并将引用的Bean的实例注入到UserServices类中。

    配置方法2:

    <bean id="userBean" class="com.kay.bean.UserBean"/>

    <bean id="userServices" class="com.kay.bean.UserServices">

    <property name="ub"><ref local="userBean"/></property>

    </bean>

    上面的配置文件将原来的ref节点中的bean属性改为了local,那么local属性要求引用的Bean必须在同一配置文件中(Spring支持多配置文件)。但是bean属性则没有这个要求。

    配置方法3:

    <bean id="userServices" class="com.kay.bean.UserServices">

    <property name="ub">

    <bean class="com.kay.bean.UserBean"/>

    </property>

    </bean>

    上面的这种配置方式成为内部Bean配置。内部Bean的定义不需要有id或name的指定,如果你指定也会被Spring容器忽略。这样配置的缺陷是引用的Bean无法得到重用,并且内部Bean是prototype的。

    配置方法4:

    <bean id="userBean" class="com.kay.bean.UserBean"/>

    <bean id="userServices" class="com.kay.bean.UserServices">

    <property name="ub" ref="userBean"/>

    </bean>

    这种写法只是配置方法1的简写形式。

    2. 构造方法注入

    从注入方面的名称上就可以看出,这种注入方式主要利用的是构造方法。把UserServices类修改为:

    package com.kay.bean;

    public class UserServices {

    private UserBean userBean;

    public UserServices(UserBean userBean){

    this.userBean = userBean;

    }

    public void add(){

    userBean.add();

    }

    }

    配置方法1:

    <bean id="userBean" class="com.kay.bean.UserBean"/>

    <bean id="userServices" class="com.kay.bean.UserServices">

    <constructor-arg>

    <ref bean="userBean"/>

    </constructor-arg>

    </bean>

    上面使用了constructor-arg节点,该节点的ref子结点bean属性指定了要引用的Bean。

    如果在UserServices类中有这样的构造方法:

    package com.kay.bean;

    public class UserServices {

    private String name;

    public int a;

    public UserServices(String name,int a){

    this.name = name;

    this.a = a;

    }

    }

    那么可以使用配置方法2和配置方法3来解决。

    配置方法2:

    <bean id="userServices" class="com.kay.bean.UserServices">

    <constructor-arg type="java.lang.String" value="Tom"/>

    <constructor-arg type="int" value="25"/>

    </bean>

    在配置方法2中使用type属性指定了构造方法参数的类型,value指定参数的值。

    配置方法3:

    <bean id="userServices" class="com.kay.bean.UserServices">

    <constructor-arg index="0" value="Tom"/>

    <constructor-arg index="1" value="25"/>

    </bean>

    在配置方法3中使用index属性指定构造方法中的参数的顺序。

    使用构造方法注入还是set注入?

    首先告诉你该问题没有答案!!!

    使用构造方法注入的理由:

    n 构造方法注入使用强依赖规定,如果不给足够的参数,对象则无法创建。

    n 由于Bean的依赖都通过构造方法设置了,那么就不用写更多的set方法,有助于减少代码量。

    使用set注入的理由:

    n 如果Bean有很多的依赖,那么构造方法的参数列表会变的很长。

    n 如果一个对象有多种构造方法,构造方法会造成代码量增加。

    n 如果构造方法中有两个以上的参数类型相同,那么将很难确定参数的用途。

    n ……

    Spring官方更推荐使用set注入。

    更多注入:

    从User类来开始:

    public class User {

    private int age;

    private String name;

    private double score;

    private List fav;

    private Map map;

    private Set set;

    private Properties pro;

    public void setAge(int age) {

    this.age = age;

    }

    public void setName(String name) {

    this.name = name;

    }

    public void setScore(double score) {

    this.score = score;

    }

    public void setFav(List fav) {

    this.fav = fav;

    }

    public void setMap(Map map) {

    this.map = map;

    }

    public void setSet(Set set) {

    this.set = set;

    }

    public void setPro(Properties pro) {

    this.pro = pro;

    }

    }

    1. 注入直接变量(基本数据类型,String类型等)

    <bean id="user" class="com.kay.bean.User">

    <property name="age" value="45"></property>

    <property name="name" value="Tom"></property>

    <property name="score" value="45.5"></property>

    </bean>

    或:

    <bean id="user" class="com.kay.bean.User">

    <property name="age">

    <value>45</value>

    </property>

    <property name="name">

    <value>Tom</value>

    </property>

    <property name="score">

    <value>45.5</value>

    </property>

    </bean>

    当然构造方法注入的方式也是可以的:

    <bean id="user" class="com.kay.bean.User">

    <constructor-arg type="int" value="45"></constructor-arg>

    <constructor-arg type="double" value="45.5"></constructor-arg>

    <constructor-arg type="java.lang.String" value="Tom"></constructor-arg>

    </bean>

    2. 集合

    a) List

    <property name="fav">

    <list>

    <value>football</value>

    <value>pingpang</value>

    <value>swing</value>

    </list>

    </property>

    b) Set

    <property name="set">

    <set>

    <value>set1</value>

    <value>set2</value>

    <value>set3</value>

    </set>

    </property>

    c) Map

    <property name="map">

    <map>

    <entry>

    <key>

    <value>id</value>

    </key>

    <value>001</value>

    </entry>

    <entry>

    <key>

    <value>name</value>

    </key>

    <value>jerry</value>

    </entry>

    </map>

    </property>

    d) Properties

    <property name="pro">

    <props>

    <prop key="name">Tom</prop>

    <prop key="age">15</prop>

    </props>

    </property>

    3. Null

    配置节点<null/>用于处理null值。

    <property name="name">

    <null></null>

    </property>

    上述配置相当于setName(null);

    如果这样配置:

    <property name="name">

    <value></value>

    </property>

    则相当于setName(“”);

    4. 使用p命名空间进行属性注入

    修改配置文件的schema:

    <?xml version="1.0" encoding="UTF-8"?>

    <beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:p="http://www.springframework.org/schema/p"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    </beans>

    注入属性:

    <bean id="user" class="com.kay.bean.User" p:name="tom" p:age="45" p:score="55.5">

    </bean>

    在上面的设置中使用了命名空间p,p:name则代表给name属性进行赋值,如果User类中有一个属性需要引用其他的Bean,则需要这样配置p:属性名-ref=”要引用的Bean”:

    <bean id="userBean" class="com.kay.bean.UserBean"/>

    <bean id="user" class="com.kay.bean.User" p:name="tom" p:age="45" p:score="55.5" p:userbean-ref="userBean">

    </bean>

    5. Bean的自动装配(注入)

    Spring提供了以下四种自动装配类型:

    n byName à试图在容器中寻找和需要自动装配的属性名相同的Bean(或ID)。如果没有找到,这个属性就没有被转配上。

    n byType à 试图在容器中寻找一个与需要自动装配的属性类型相同的Bean。如果没有找到相符的Bean,这个属性就没有被装配,如果找到超过一个相符的Bean,会抛出org.springframework.bean.factory.UnsatisfiedDependencyException异常。

    n Constructor à试图在容器中查找与需要自动装配的Bean的构造函数一致的一个或多个Bean。古国存在不确定的Bean或构造函数,容器抛出org.spingframework.beans.factory. UnsatisfiedDependencyException异常。

    n Autodetect à首先尝试使用constrctor来装配,然后采用byType方式。不确定性的处理与constrctor和byType方式一样。

    使用byName进行自动装配:

    UserDAO类:

    public class UserDAO {

    public void add(){

    System.out.println("使用JDBC进行添加操作");

    }

    }

    UserServices类:

    public class UserServices {

    private UserDAO userDAO;

    public void setUserDAO(UserDAO userDAO) {

    this.userDAO = userDAO;

    }

    public void add(){

    userDAO.add();

    }

    }

    使用byName自动装配:

    <bean id="userDAO" class="com.kay.bean.UserDAO"></bean>

    <bean id="userService" class="com.kay.bean.UserServices" autowire="byName">

    </bean>

    在使用byName自动装配的时候,需要将Bean中注入的属性名设置为和要注入的Bean名称一样。(黄色部分)

    使用byType进行自动装配:

    在使用byType进行自动装配的时候,和使用byName进行装配工作方式的相同的,只不过是通过属性的类型进行寻找相关Bean进行装配的。

    <bean id="userDAO" class="com.kay.bean.UserDAO"></bean>

    <bean id="userService" class="com.kay.bean.UserServices" autowire="byType">

    </bean>

    在使用buType自动装配的时候,如果Spring找到和需要注入的Bean的类型相同的Bean个数超过了一个,Spring不会决定将哪个Bean注入,而是直接抛出异常。

    使用constructor进行自动装配:

    修改UserService类:

    public class UserServices {

    private UserDAO userDAO;

    public UserServices( UserDAO userDAO)

    {

    this.userDAO = userDAO;

    }

    public void add(){

    userDAO.add();

    }

    }

    修改配置文件:

    <bean id="userDAO" class="com.kay.bean.UserDAO"></bean>

    <bean id="userService" class="com.kay.bean.UserServices" autowire="constructor">

    </bean>

    在使用constructor进行自动转配的时候,Spring容器会寻找匹配Bean的构造方法的Bean进行注入,和ByType一样,如果容器找到一个以上的匹配Bean,同样不会决定将哪个Bean进行注入,而是抛出异常。

    使用autodetect自动装配:

    <bean id="userService" class="com.kay.bean.UserServices" autowire="autodetect">

    </bean>

    将atuowire属性值设置为autodetect,那么将由Spring容器决定使用哪种装配方式。容器会先尝试使用constructor进行装配,如果失败则会使用byTyep进行装配。

    在默认的情况下,Spring容器不会进行自动装配,除非在配置文件中设置了autowire属性,如果设置beans节点的default-autowire属性,那么所有的Bean都会采用自动装配。

    <beans default-autowire="byName">

    </beans>

    采用上述设置后,所有的Bean都采用byName方式进行装配。

  • 相关阅读:
    P4720 【模板】扩展卢卡斯
    P3211 [HNOI2011]XOR和路径
    ZOJ 3329 One Person Game
    CF817F MEX Queries
    P3239 [HNOI2015]亚瑟王
    P3412 仓鼠找sugar II
    P4111 [HEOI2015]小Z的房间
    P4008 [NOI2003]文本编辑器
    CF451E Devu and Flowers
    P3975 [TJOI2015]弦论
  • 原文地址:https://www.cnblogs.com/kay/p/1456695.html
Copyright © 2020-2023  润新知