[笔记]Spring-Day1 — IOC&DI

学什么

简化开发: Spring框架中提供了两个大的核心技术

  • IOC

  • AOP

核心概念

IOC & IOC容器 & Bean

  • IOC(Inversion of Control)控制反转

  • 不自己new对象,交给容器new -- 解耦

  • IOC容器负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象

  • 被创建或被管理的对象在IOC容器中统称为Bean

DI

  • (Dependency Injection)依赖注入

  • 建立容器中对象与对象之间的绑定关系

  • service运行需要依赖dao对象

案例

解耦BookDao

  1. pom.xml添加依赖

  2. 添加案例中需要的类

  3. 添加spring配置文件applicationContext.xml

         <?xml version="1.0" encoding="UTF-8"?>
         <beans xmlns="http://www.springframework.org/schema/beans"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <!--1.导入spring的坐标spring-context-->
       <!--2.配置bean-->
       <!--bean标签标示配置bean
           id属性标示给bean起名字
           class属性表示给bean定义类型
           注意class不要写成接口类而是实现类,因为bean要找对象
             -->
         	<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
             <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"/>
         
         </beans>
  4. 获取IOC容器、从容器中获取对象进行方法调用

       ```java
       public class App {
           public static void main(String[] args) {
               //获取IOC容器
       		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 
       //getBean() 方法获取的 Bean 的标识符(id 或 name 属性的值),返回的是一个通用的 Object 类型,我们需要将其转换为 BookService 类型
       //        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
       //        bookDao.save();
               BookService bookService = (BookService) ctx.getBean("bookService");
               bookService.save();
           }
       }
       ```
     
  5. 运行程序测试

解耦BookService

  1. 去除BookServiceImpl中的new,为属性提供setter方法

         public class BookServiceImpl implements BookService {
             //删除业务层中使用new的方式创建的dao对象
             private BookDao bookDao;
         
             public void save() {
                 System.out.println("book service save ...");
                 bookDao.save();
            
             //提供对应的set方法
             public void setBookDao(BookDao bookDao) {
                 this.bookDao = bookDao;
             }
         }
  2. 修改配置完成注入

         <?xml version="1.0" encoding="UTF-8"?>
         <beans xmlns="http://www.springframework.org/schema/beans"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
             <!--bean标签标示配置bean
             	id属性标示给bean起名字
             	class属性表示给bean定义类型-->
             <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
         
             <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
                 <!--配置server与dao的关系-->
                 <!--property标签表示配置当前bean的属性
                 		name属性表示配置哪一个具体的属性/对象名称
                 		ref属性表示参照哪一个bean-->
                 <property name="bookDao" ref="bookDao"/>
             </bean>
         </beans>
  3. 运行程序

关于bean

bean的基础配置

配置别名 name

<!--name:为bean指定别名,别名可以有多个,使用逗号,分号,空格进行分隔-->
    <bean id="bookService" name="service service4 bookEbi" class="com.itheima.service.impl.BookServiceImpl">
             <property name="bookDao" ref="bookDao"/>
    </bean>

配置范围(是否为单例) scode

    <!--scope:为bean设置作用范围,可选值为单例singloton,非单例prototype-->
    <bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl"/>
    </beans>

bean的实例化

构造方法实例化 — 无参构造方法

在BookDaoImpl类中添加一个无参构造函数,并打印一句话,方便观察结果

静态工厂实例化 — 了解即可

实例工厂化 — 额额不太懂

  1. 准备一个Dao和DaoImpl类

  2. 创建一个工厂类OrderDaoFactory并提供一个普通方法

public class UserDaoFactory {
  }
}
  • 创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法

public class UserDaoFactoryBean implements FactoryBean<UserDao> {
//代替原始实例工厂中创建对象的方法
//替代UseDaoFactory的getUserDao方法
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
//返回所创建类的Class对象
public Class<?> getObjectType() {
        return UserDao.class;
        }
    }
  1. 配置文件添加

    <bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
  2. 编写AppForInstanceUser运行类,在类中通过工厂获取对象

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

bean的生命周期

bean对象从创建到销毁的整体过程

  • 初始化容器

    • 1.创建对象(内存分配)

    • 2.执行构造方法

    • 3.执行属性注入(set操作)

    • 4.执行bean初始化方法

  • 使用bean

    • 执行业务操作

  • 关闭/销毁容器

    • 执行bean销毁方法

  • 代码实现

    • 1.init&destory

      //添加两个接口`InitializingBean`, `DisposableBean`并实现接口中的两个方法`afterPropertiesSet`和`destroy`
      //这样就不用在配置文件里面配置`init-method`和`destroy-method`
      public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
              private BookDao bookDao;
              public void setBookDao(BookDao bookDao) {
                 this.bookDao = bookDao;
              }
              public void save() {
                  System.out.println("book service save ...");
                 bookDao.save(); 
              }
              public void destroy() throws Exception {
                 System.out.println("service destroy");
               }
              public void afterPropertiesSet() throws Exception {
                 System.out.println("service init");
               }
           }
    • 2.close —执行destroy方法的内容

          //ApplicationContext中没有close方法,需要将ApplicationContext更换成ClassPathXmlApplicationContext
          ClassPathXmlApplicationContext ctx = new 
          ClassPathXmlApplicationContext("applicationContext.xml");
          //运行程序,就能执行destroy方法的内容
          ctx.close();
    • 3.注册钩子关闭容器 — 执行destroy方法的内容

      ctx.registerShutdownHook();

DI

相关内容

setter注入

  • 简单类型

    <bean ...>
        <property name="" value=""/>
    </bean>
  • 引用类型

    <bean ...>
    	<property name="" ref=""/>
    </bean>

构造器注入

  • 简单类型

    <bean ...>
    	<constructor-arg name="" index="" type="" value=""/>
    </bean>
  • 引用类型

    <bean ...>
    	<constructor-arg name="" index="" type="" ref=""/>
    </bean>

自动配置

  • 不用写配置文件了

  • 类型

按类型(常用)

    <bean class="com.itheima.dao.impl.BookDaoImpl"/>
        <!--autowire属性:开启自动装配,通常使用按类型装配-->
        <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"/>
    </beans>

按名称 — 有多个相同类型的对象

    <bean class="com.itheima.dao.impl.BookDaoImpl"/>
        <!--autowire属性:开启自动装配,通常使用按类型装配-->
        <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byName"/>
    </beans>

按构造方法

集合注入

数组类型数据

    <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>

最后更新于