IoC 与 DI笔记

Ioc

控制反转IoC,一种设计思想,是spring的核心。所谓IoC,就是Spring来负责控制对象的生命周期和对象间的关系。类在spring容器中登记后,告诉spring你需要什么类,然后spring会把你需要的类给你,同时spring也会在别的类需要你的时候把你交给它。

DI

依赖注入,是实现控制反转的一种方法

●谁依赖于谁:当然是应⽤程序依赖于IoC容器;
●为什么需要依赖:应⽤程序需要IoC容器来提供对象需要的外部资源;
●谁注⼊谁:很明显是IoC容器注⼊应⽤程序某个对象,应⽤程序依赖的对象;
●注⼊了什么:就是注⼊某个对象所需要的外部资源(包括对象、资源、常量数据)。

运用IoC解决程序解耦

1.编写业务层接口和实体类

//接口
public interface IAccountService { 
    //保存账户(此处只是模拟,并不是真的要保存) 
    void saveAccount(); 
}
//实现类
public class AccountServiceImpl implements IAccountService { 
    private IAccountDao accountDao = new AccountDaoImpl();//此处的依赖关系有待解决
    public void saveAccount() { 
        accountDao.saveAccount();
    } 
}

2.创建持久层和实体类

//接口
public interface IAccountDao { 
    //保存账户 
    void saveAccount();     
}

//实现类 
public class AccountDaoImpl implements IAccountDao { 
    public void saveAccount() { 
        System.out.println("保存了账户");
    } 
}

3.让spring管理资源,在配置文件中配置service和dao

<!-- bean 标签:用于配置让 spring 创建对象,并且存入 ioc 容器之中 id 属性:对象的唯一标识。 class 属性:指定要创建对象的全限定类名--> 
<!-- 配置 service --> 
<bean id="accountService" class="com.zx.service.impl.AccountServiceImpl"> 
</bean> 
<!-- 配置 dao -->
 <bean id="accountDao" class="com.zx.dao.impl.AccountDaoImpl">
</bean>

4.测试配置的主函数

public static void main(String[] args) { 
    //1.使用 ApplicationContext 接口,就是在获取 spring 容器 
    ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); 
    //2.根据 bean 的 id 获取对象 
    IAccountService aService = (IAccountService) ac.getBean("accountService"); 
    System.out.println(aService);
    IAccountDao aDao = (IAccountDao) ac.getBean("accountDao"); 
    System.out.println(aDao);

spring工厂结构图

BeanFactory和ApplicationContext的区别

BeanFactory 才是 Spring 容器中的顶层接口。
ApplicationContext 是它的子接口。

BeanFactory 和 ApplicationContext 的区别:
创建对象的时间点不一样。 ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。 BeanFactory:什么使用什么时候创建对象。

ApplicationContext 接口的实现类

ClassPathXmlApplicationContext: 它是从类的根路径下加载配置文件---------------推荐使用这种
FileSystemXmlApplicationContext:它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
AnnotationConfigApplicationContext: 当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

Bean标签和管理对象的细节

Bean标签

  • 作用:
    用于配置对象让 spring 来创建的。 默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。
  • 属性:
    id:给对象在容器中提供一个唯一标识。用于获取对象。
    class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
    init-method:指定类中的初始化方法名称。
    destroy-method:指定类中销毁方法名称。
    scope:指定对象的作用范围:
    • singleton :默认值,单例的.
    • prototype :多例的.
    • request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
    • session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.

      Bean的作用范围和生命周期:

  • 单例对象:scope="singleton"
    一个应用只有一个对象的实例。它的作用范围就是整个引用。 生命周期:
    对象出生:当应用加载,创建容器时,对象就被创建了。 对象活着:只要容器在,对象一直活着。
    对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
  • 多例对象:scope="prototype"
    每次访问对象时,都会重新创建对象实例。 生命周期:
    对象出生:当使用对象时,创建新的对象实例。 对象活着:只要对象在使用中,就一直活着。
    对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

    实例化Bean的三种方式

  • 第一种方式:使用默认无参构造函数
<!--在默认情况下:
它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败。--> 
<bean id="accountService" class="com.zx.service.impl.AccountServiceImpl"/>
  • 第二种方式:spring管理静态工厂-使用静态工厂的方法创建对象
// 模拟一个静态工厂,创建业务层实现类 
public class StaticFactory { 
    public static IAccountService createAccountService(){ 
        return new AccountServiceImpl();
    } 
}
<!-- 此种方式是: 使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器 
id 属性:指定 bean 的 id,用于从容器中获取 
class 属性:指定静态工厂的全限定类名 
factory-method 属性:指定生产对象的静态方法
-->
<bean id="accountService" class="com.zx.factory.StaticFactory" factory-method="createAccountService"></bean>
  • 第三种方式:spring管理实例工厂-使用实例工厂的方法创建对象
//模拟一个实例工厂,创建业务层实现类 
//此工厂创建对象,必须现有工厂实例对象,再调用方法
public class InstanceFactory { 
    public IAccountService createAccountService(){     
        return new AccountServiceImpl();
    } 
} 
<!-- 此种方式是:
先把工厂的创建交给 spring 来管理。 然后在使用工厂的 bean 来调用里面的方法 
factory-bean 属性:用于指定实例工厂 bean 的 id。 
factory-method 属性:用于指定实例工厂中创建对象的方法。
--> 
<bean id="instancFactory" class="com.zx.factory.InstanceFactory"></bean> 
<bean id="accountService" factory-bean="instancFactory" factory-method="createAccountService"></bean>

依赖注入

  • 使用构造函数的方式,给 service 中的属性传值
要求:
类中需要提供一个对应参数列表的构造函数。
涉及的:
        标签: constructor-arg 
        属性:
               index:指定参数在构造函数参数列表的索引位置 
               type:指定参数在构造函数中的数据类型
               name:指定参数在构造函数中的名称 用这个找给谁赋值 
               =======上面三个都是找给谁赋值,下面两个指的是赋什么值的==============
               value:它能赋的值是基本数据类型和 String 类型 
               ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
  • 通过配置文件给 bean 中的属性传值,使用 set 方法的方式
     涉及的:
            标签: property
            属性:
                  name:找的是类中set 方法后面的部分
                  ref:给属性赋值是其他 bean 类型的
                  value:给属性赋值是基本数据类型和 string 类型的
    实际开发中,此种方式用的较多。

猜你喜欢

转载自www.cnblogs.com/programmerzx/p/12333583.html
今日推荐