Spring-依赖注入

Spring入门这一章中,验证了通过IoC创建对象,没有调用业务层的保存用户的方法,当你调用业务层方法时,会出现如下错误:
在这里插入图片描述
很明显,虽然我们通过控制反转获得到持久层和业务层的对象,但是对象之间并没有什么任何关系,因此才会出现空指针异常的错误。怎么把持久层对象传入业务层呢???这就需要 依赖注入(Dependency Injection) 了。

依赖注入方式一 : 构造函数注入

使用构造函数的方式,给属性赋值。

/**
 * 账户的业务层实现类
 */
public class AccountServiceImpl implements AccountService {

    private String name;
    private Double money;
    private Date birthday;
    public AccountServiceImpl(String name,Date birthday,Double money)
    {
        this.name = name;
        this.money = money;
        this.birthday = birthday;
    }
    public void saveAccount() {
        System.out.println("账户信息为   姓名:"+name+"  生日:"+birthday+"  余额:"+money);
    }
}

通过配置方式给有参构造函数的属性赋值

    <bean id="accountService" class="com.liang.service.impl.AccountServiceImpl">
        <constructor-arg name="name" value="张三"></constructor-arg>
        <constructor-arg name="birthday" ref="birthday"></constructor-arg>
        <constructor-arg name="money" value="100.0"></constructor-arg>
    </bean>
    <bean id="birthday" class="java.util.Date"></bean>

constructor-org标签属性说明

属性 功能
index 参数在构造函数参数列表的索引位置
type 参数在构造函数中的数据类型
name 参数在构造函数中的名称
value 用于给基本类型和String类型赋值
ref 能将其他类型的bean赋值给属性

依赖注入方式二 : set方法注入

需要注入的成员提供set方法。

/**
 * 账户的业务层实现类
 */
public class AccountServiceImpl implements AccountService {

    private String name;
    private Double money;
    private Date birthday;

    public void setName(String name) {
        this.name = name;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public void saveAccount() {
        System.out.println("账户信息为   姓名:"+name+"  生日:"+birthday+"  余额:"+money);
    }
}

通过配置文件给bean中属性赋值,使用set方法的方式。

 <bean id="accountService" class="com.liang.service.impl.AccountServiceImpl">
        <property name="name" value="张三"></property>
        <property name="birthday" ref="birthday"></property>
        <property name="money" value="100.0"></property>
    </bean>
    <bean id="birthday" class="java.util.Date"></bean>

property标签属性说明

属性 功能
name 类中set方法后面的部分(首字母小写)
ref 将其他bean类型赋值给属性
value 将基本类型和String类型赋值给属性

依赖注入方式三 : 使用p名称空间注入数据

在xml配置文件中导入p名称空间,使用p:属性名 来注入数据,其本质是set方式注入。

/**
 * 账户的业务层实现类
 */
public class AccountServiceImpl implements AccountService {

    private String name;
    private Double money;
    private Date birthday;

    public void setName(String name) {
        this.name = name;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public void saveAccount() {
        System.out.println("账户信息为   姓名:"+name+"  生日:"+birthday+"  余额:"+money);
    }
}

配置文件:引入p名称空间: xmlns:p=“http://www.springframework.org/schema/p”

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="accountService" class="com.liang.service.impl.AccountServiceImpl" p:name="张三" p:money="100.0" p:birthday-ref="birthday"></bean>
    <bean id="birthday" class="java.util.Date"></bean>
</beans>

集合类型属性注入

变量的数据类型都是集合类型,例如数组、List、 Set、 Map、 Properties类型的变量注入。

public class AccountServiceImpl implements AccountService {

    private String[] str;
    private List<String> list;
    private Set<String> set;
    private Map<String,String> map;
    private Properties properties;

    public void setStr(String[] str) {
        this.str = str;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public void saveAccount() {
        System.out.println("数组:" + str);
        System.out.println("List:" + list);
        System.out.println("Set:" + set);
        System.out.println("Map:" + map);
        System.out.println("Properties" + properties);
    }

}

配置文件

  <bean id="accountService" class="com.liang.service.impl.AccountServiceImpl">
        <!--给数组注入数据-->
        <property name="str">
            <set>
                <value>娃哈哈</value>
                <value>AD钙</value>
            </set>
        </property>
        <!--注入list集合数据-->
        <property name="list">
            <list>
                <value>小河</value>
                <value>小马</value>
            </list>
        </property>
        <!--注入set集合数据-->
        <property name="set">
            <set>
                <value>张三</value>
                <value>李四</value>
            </set>
        </property>
        <!--注入map集合数据-->
        <property name="map">
            <map>
                <entry key="key1" value="Values1"></entry>
                <entry key="key2" value="Values2"></entry>
                <entry key="key3">
                    <value>Values3</value>
                </entry>
            </map>
        </property>
        <!--注入properties数据-->
        <property name="properties">
            <props>
                <prop key="testA">A</prop>
                <prop key="testB">B</prop>
            </props>
        </property>
    </bean>

测试

    @Test
    public void configTest()
    {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        AccountService accountService = (AccountService)applicationContext.getBean("accountService");
        System.out.println(accountService);
        accountService.saveAccount();
    }

在注入集合数据时,只要结构相同,则标签可以互换。
那么本文开始提到的问题则可以通过上述方式进行解决
。例如:

public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void saveAccount() {
       accountDao.saveAccount();
    }

}

配置文件

    <bean id="accountDao" class="com.liang.dao.impl.AccountDaoImpl"></bean>
    <bean id="accountService" class="com.liang.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>

测试

  @Test
    public void configTest()
    {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        AccountService accountService = (AccountService)applicationContext.getBean("accountService");
        System.out.println(accountService);
        accountService.saveAccount();
    }
发布了71 篇原创文章 · 获赞 6 · 访问量 5382
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章