Spring 依赖注入

Spring依赖注入

构造器注入

构造器注入需要有带参数的构造方法

在xml中只需在标签内加上标签

其中:


  • name指的是这个属性的名字(实际上是构造方法中的参数名)

  • value是这个属性的值可以用来对基本类型和String类型进行赋值

  • ref 如果属性的类型是复杂对象的引用类型,可以用ref引用其他bean标签

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

public class TestProxyServiceImpl implements TestProxyService {
    private User user;
    private String name;

    public TestProxyServiceImpl(User user,String name) {
        this.user = user;
        this.name = name;
    }

    @Override
    public void sayhello() {
        System.out.println("hello" + user+","+name);
    }
}

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

<bean id="user" class="com.mb.msgboards.vo.User"/>
<bean id="proxyService" class="com.mb.msgboards.service.impl.TestProxyServiceImpl">
    <constructor-arg name="user" ref="user"/>
    <constructor-arg name="name" value="myname"/>
</bean>

这种指定name来注入属性的方式显得有些耦合 ,name中指定的其实是构造方法的参数名,这可能会和属性名不一致,如果参数名被修改,那么对应的配置也要修改,耦合度太高

于是有了以下方案:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

    <bean id="user" class="com.mb.msgboards.vo.User"/>
    <bean id="proxyService" class="com.mb.msgboards.service.impl.TestProxyServiceImpl">
        <constructor-arg type="com.mb.msgboards.vo.User" ref="user"/>
        <constructor-arg type="java.lang.String" name="name" value="myname"/>
    </bean>

通过指定类型来对属性进行注入,可以自动匹配属性类型,但是对于多个相同类型的属性,这种也无法指定唯一确定的属性,于是又有了下面这种方式:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

    <bean id="user" class="com.mb.msgboards.vo.User"/>
    <bean id="proxyService" class="com.mb.msgboards.service.impl.TestProxyServiceImpl">
        <constructor-arg index="0" ref="user"/>
        <constructor-arg index="1" value="myname"/>
    </bean>

直接通过指定构造方法的参数数序来进行匹配注入,这种方式可以避免属性名或参数名的修改导致配置失效的问题,也避免了类型相同导致的无法确定唯一属性的问题

构造器注入还有个好处是:对于构造器参数中的属性,一定不会漏掉配置,如果漏配置会xml文件会报错,相较于setter注入更严谨

Setter注入

setter注入时类中必须要有对这个属性的setter方法

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

public class TestProxyServiceImpl implements TestProxyService {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void sayhello() {
        System.out.println("hello" + name);
    }
}

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

<bean id="proxyService1" class="com.mb.msgboards.service.impl.TestProxyServiceImpl">
    <property name="name" value="zzz"/>
</bean>

在xml中只需在标签内加上标签

其中:


  • name指的是这个属性的名字(实际上是set方法名中set后的字符串)

  • value是这个属性的值可以用来对基本类型和String类型进行赋值

  • ref 如果属性的类型是复杂对象的引用类型,可以用ref引用其他bean标签

引用类型例子:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

<bean id="user" class="com.mb.msgboards.vo.User"/>
<bean id="proxyService" class="com.mb.msgboards.service.impl.TestProxyServiceImpl">
    <property name="user" ref="user"/>
</bean>

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

public class TestProxyServiceImpl implements TestProxyService {
    private User user;
    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public void sayhello() {
        System.out.println("hello" + user);

    }
}

setter注入的方式是可选注入,如果类中存在不能为null的属性,建议使用构造器注入,setter注入方式可能会导致属性为null,因为setter不是必须,可能会漏掉配置