IOC(Inversion Of Control): 控制反转

    1. 控制: 资源的获取方式:

      • 主动式:

        1. BookServlet{
        2. BookService bs = new BookService();
        3. AirPlan ap = new AirPlane(); //复杂对象的创建是比较庞大的工厂
        4. }
      • 被动式: 资源的获取不是自己来创建, 而是交给容易来创建和设置

        1. BookServlet{
        2. BookService bs;
        3. public void test1(){
        4. bs.checkout();
        5. }
        6. }
    2. 容器: 管理所有的组件(有功能的类), 假设: BookServlet受容器管理, BookService也受容器管理,容器可以自动的探查出哪些组件(类)需要用到哪些组件(类), 容器帮我们创建BookService对象, 并把BookService对象赋值过去.
      主动地new资源变成被动的接受资源

    3. DI(Dependency Injection) 依赖注入:
      容器能知道哪个组件运行的时候,需要另外一个组件; 容器通过反射的形式, 将容器中准备好的BookService对象注入(利用反射给属性赋值)到BookServlet.
      只要是容器管理的组件, 都能使用容器提供的功能.


    HelloWorld:
    给容器注册组件.

    1. 导包
    2. 写配置```xml <?xml version=”1.0” encoding=”UTF-8”?> <beans xmlns=”http://www.springframework.org/schema/beans
      1. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      2. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
       <property name="lastName" value="张三"></property>
       <property name="age" value="18"></property>
       <property name="email" value="100@qq.com"></property>
       <property name="gender" value="男"></property>
      
      ```
    1. 测试```java public class PersonTest { /**

      • @description 从容器中拿到组件
      • @param
      • @return void */ @Test public void test() { // ApplicationContext, 代表ioc容器 // 当前应用的xml配置文件在ClassPath下 // 根据spring配置文件的到ioc容器对象 ApplicationContext ioc = new ClassPathXmlApplicationContext(“ioc.xml”); // 当前应用的xml配置文件路径通过文件系统查找 //ApplicationContext ioc = new FileSystemXmlApplicationContext(“ioc.xml”);

        Person person = (Person) ioc.getBean(“person01”); System.out.println(person); } } ```

    细节:

    1. ApplicationContext就是IOC容器接口

    2. 给容器中注册一个组件, 可以通过容器中组件的唯一标识id拿到组件的实例

      • 组件的创建是由容器完成的
      • 对象的创建(实例化)是在容器创建完成的时候就创建好了
      • 同一个组件在容器中只有一份(单实例)
      • 没有注册的实例会报异常No bean named 'xxx' is defined
      • 组件实例的赋值是通过setter赋值的
      • javaBean的属性名是由getter/setter方法决定的, 不是由声明的成员属性决定. (注意: boolean类型的属性的setter方式是isXxxx)
    3. 通过bean类型获取容器中注册的组件

      @Test
      public void test2() {
       Person bean = ioc.getBean(Person.class);
       System.out.println(bean);
      
       Person person01 = ioc.getBean("person01", Person.class);
      }
      
    • 使用该方法不需要类型强转
    • 该方式要求所传类型的组件在配置文件中只注册了一个, 如果注册了多个相同类型的组件,则会报错类似:java No qualifying bean of type [com.yguilai.bean.Person] is defined: expected single matching bean but found 2: bean01,bean02
    • 也可以通过ioc.getBean("person01", Person.class);传入组件的id和类型的方式获取实例, 该方式支持容器中同类型组件注册了多个.
      1. 通过有参构造器创建组件
        <bean id="person03" class="com.yguilai.bean.Person">
        <!--    调用有参构造器进行创建对象并赋值    -->
        <constructor-arg name="lastName" value="小明"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="email" value="111@qq.com"></constructor-arg>
        <constructor-arg name="gender" value="男"></constructor-arg>
        </bean>