DI(依赖注入)

182 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

依赖注入方式

\

image.png

setter注入---引用类型

\

image.png

setter注入的步骤

1.在对应的类中创建相应的set方法

image.png

2.在配置文件中定义变量的值

image.png

3.运行即可体现setter注入

image.png

构造器注入

构造器注入的步骤

下列操作都基于此类完成

public class BookServiceImpl implements BookService{
    private BookDao bookDao;
    private UserDao userDao;

    public BookServiceImpl(BookDao bookDao, UserDao userDao) {
        this.bookDao = bookDao;
        this.userDao=userDao;
    }

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
}

1.在对应类中创建属性,并在构造器中的参数填入这些属性

public class UserDaoImpl implements UserDao {
    private int id;
    private String name;


    public UserDaoImpl(int id,String name) {
        this.id=id;
        this.name=name;
    }
    public void save() {
        System.out.println("book dao save ..."+id+","+name);
    }
}

2.在配置文件中如下进行配置

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <constructor-arg index="0" value="24"/>
    <constructor-arg index="1" value="小卡斯蒂"/>
</bean>

index=索引位置 也可以用name=形参名字 来代替也可以使用 type=类型

后两种方法可以解决耦合问题,index=索引位置 推荐使用

3.调用方法即可

public static void main( String[] args ) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    BookService bookService = (BookService) ctx.getBean("bookService");
    bookService.save();
}

image.png

依赖注入方式选择

1.强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现

2.可选依赖使用setter注入进行,灵活性强

3.Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨

4.如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注

5.实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入

6.自己开发的模块推荐使用setter注入

依赖自动装配

  • IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配

  • 自动装配方式

    • 按类型(常用):直接在配置文件中按如下所示进行配置

好处:不用在配置文件中取名,直接如下图即可

\

image.png

    • 局限:若配置文件中有两种及以上同类型配置,或在配置文件中未定义该类型的类,则无法使用"byType"

    • 按名称

      需要在配置文件中定义与class对应类中的相同类的对象的名称

    • 按构造方法

    • 不启用自动装配

依赖自动装配特征

  • 自动装配用于引用类型依赖注入,不能对简单类型进行操作
  • 使用按类型装配时( byType )必须保障容器中相同类型的bean唯一,推荐使用
  • 使用按名称装配时( byName )必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
  • 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效

集合注入

<!--数组注入-->
    <property name="array">
        <array>
            <value>100</value>
            <value>200</value>
            <value>300</value>
        </array>
    </property>
    <!--list集合注入-->
    <property name="list">
        <list>
            <value>itcast</value>
            <value>itheima</value>
            <value>boxuegu</value>
            <value>chuanzhihui</value>
        </list>
    </property>
    <!--set集合注入-->
    <property name="set">
        <set>
            <value>itcast</value>
            <value>itheima</value>
            <value>boxuegu</value>
            <value>boxuegu</value>
        </set>
    </property>
    <!--map集合注入-->
    <property name="map">
        <map>
            <entry key="country" value="china"/>
            <entry key="province" value="henan"/>
            <entry key="city" value="kaifeng"/>
        </map>
    </property>
    <!--Properties注入-->
    <property name="properties">
        <props>
            <prop key="country">china</prop>
            <prop key="province">henan</prop>
            <prop key="city">kaifeng</prop>
        </props>
    </property>
</bean>
public class BookDaoImpl implements BookDao {
private int[] array;

    private List<String> list;

    private Set<String> set;

    private Map<String,String> map;

    private Properties properties;
public static void main( String[] args ) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

    BookDao bookDao = (BookDao) ctx.getBean("bookDao");

    bookDao.save();
}

数据源对象管理

遇到了一个bug:

从外部导入模块时,maven会爆红。

image.png

此时,只需要再右侧maven点install操作即可

image.png

加载properties文件

1.xmlns:context="www.springframework.org/schema/cont…"在xml文件中加入此代码用来开辟名为context的空间

2.在xsi:schemaLocation="后面加入

www.springframework.org/schema/cont… www.springframework.org/schema/cont…

即将原先的bean改为context即可

3.使用context文件加载properties文件

<context:property-placeholder location="jdbc.properties"/>

4.使用${}读取properties文件中的属性

<bean  id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.passwordr}"/>
</bean>

image.png

image.png

容器

创建容器:3种方式

1.类路径加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
2.文件路径加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
3.加载多个配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml","bean21.xml");

获取bean

//1.使用bean名称获取
BookDao bookDao = (BookDao)ctx.getBean("bookDao");
//2.使用bean名称获取并指定类型
BookDao bookDao = ctx.getBean("bookDao",BookDao.class);
//3.使用bean名类型获取
但此时得保证对应的bean只能有一个  BookDao bookDao = ctx.getBean(BookDao.class);

PS:BeanFactory创建完毕后,所有的bean均为延迟加载

核心容器总结

1.BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载

2.ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载

3.ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能

4.ApplicationContext接口常用初始化类:

ClassPathXmlApplicationContext

FileSystemXmlApplicationContext

image.png

依赖注入相关

image.png