首页 > 其他分享 >Spring

Spring

时间:2023-05-29 21:12:40浏览次数:35  
标签:容器 tyhxzy Spring context import com public

一、Spring简介

优点:

简化开发

框架整合

官网:https://spring.io

image-20230526144213831

发展史

image-20230526144234481

1. Spring Framework系统架构图

image-20230526144327595

image-20230526144337404

2. 目前问题

image-20230526144434401

  • 代码书写现状
    • 耦合度偏高
  • 解决方案
    • 使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象

3. 核心概念

  • IOC(Inversion of Control)控制反转 控制权的反转 创建对象的控制权由程序员变为了spring

    使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转。通俗的讲就是“将new对象的权利交给Spring,我们从Spring中获取对象使用即可” spring提前把new好的对象存放在一个容器中,这个容器就是核心容器

  • Spring技术对IoC思想进行了实现

    • Spring提供了一个容器,称为IOC容器,用来充当IoC思想中的“外部”

    • IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean

    • DI(Dependency Injection)依赖注入

    • 类要依赖他的属性,所以我们说类的依赖就是他的属性

    • spring在创建对象时给对象的属性赋值 就称为依赖注入

    • spring ioc 容负责创建对象 我们称之为控制反转 创建对象的同时给属性赋值 我们称之为依赖注入

      • 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入。

        我们从spring ioc容器中要了一个数据访问访问层对象赋给了 bookDao这个变量 ,这个过程就叫依赖注入

image-20230526145707250

  • 目标:充分解耦
    • 使用IoC容器管理bean(IOC)
    • 在IoC容器内将有依赖关系的bean进行关系绑定(DI)
  • 最终效果
    • 使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系

二、Spring使用

1. IOC实现步骤

【第一步】导入Spring坐标
【第二步】定义Spring管理的类(接口与实现类)
【第三步】创建Spring配置文件,配置对应类作为Spring管理的bean对象
【第四步】初始化IOC容器(Spring核心容器/Spring容器),通过容器获取bean对象

【第一步】导入Spring坐标

 <dependencies>
        <!--spring核心依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.12</version>
        </dependency>

        <!--junit的依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

【第二步】定义Spring管理的类(接口)

BookDao接口和BookDaoImpl实现类

package com.tyhxzy.dao;

/**
 * 书籍的DAO接口
 */
public interface BookDao {
    /**
     添加书籍
     */
    void save();
}
package com.tyhxzy.dao.impl;

import com.tyhxzy.dao.BookDao;

/**
 * 书籍DAO的实现类
 */
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("DAO:添加书籍到数据库");
    }
}

BookService接口和BookServiceImpl实现类

package com.tyhxzy.service;

public interface BookService {
    /**
     添加书籍
     */
    void save();
}
package com.tyhxzy.service.impl;

import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;
import com.tyhxzy.service.BookService;

public class BookServiceImpl implements BookService {
    //创建成员对象
    private BookDao bookDao = new BookDaoImpl();

    //实现业务方法
    @Override
    public void save() {
        System.out.println("业务层:调用添加书籍的方法");
        bookDao.save();
    }
}

【第三步】创建Spring配置文件,配置对应类作为Spring管理的bean对象

  • 定义applicationContext.xml配置文件并配置BookServiceImpl
  • 注:如果顶部出现提示信息,选择Disable inspection

image-20230526150630401

<?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标签的作用: 创建制定类的对象并且存储到spring的容器中
        class: 指定你创建的对象所属的类的类全名
        id: 该对象在容器中的唯一标识
        -->
    <bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl"/>


</beans>

注意事项:bean定义时id属性在同一个上下文中(IOC容器中)不能重复

【第四步】初始化IOC容器(Spring核心容器/Spring容器),通过容器获取Bean对象

package com.tyhxzy.test;

import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {

    //测试:从spring的容器中获取对象
    @Test
    public void  testGetBean(){
        //        //1.创建spring的容器,读取配置文件 ,   ApplicationContext  是spring的容器的根接口。
        //ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2. 通过id从spring的容器中查找对象
        //BookService bookService = (BookService) context.getBean("bookService");

        //从容器中获取对象的时候,告诉容器对象的类型即可
        BookService bookService = context.getBean("bookService", BookService.class);
        bookService.save();

        //3。关闭容器(以后不需要关闭的)
        context.close();
    }
}

运行结果

image-20230526150813849

2. DI实现步骤

【第一步】删除使用new的形式创建对象的代码
【第二步】提供依赖对象对应的setter方法
【第三步】配置service与dao之间的关系

实现代码

【第一步】删除使用new的形式创建对象的代码

package com.tyhxzy.service.impl;

import com.tyhxzy.dao.BookDao;
import com.tyhxzy.service.BookService;

public class BookServiceImpl implements BookService {
    //【第一步】删除使用new的形式创建对象的代码,解除对象之间的耦合度
    private BookDao bookDao;

    //实现业务方法
    @Override
    public void save() {
        System.out.println("业务层:调用添加书籍的方法");
        bookDao.save();
    }
}

【第二步】提供依赖对象对应的setter方法

package com.tyhxzy.service.impl;

import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;
import com.tyhxzy.service.BookService;

public class BookServiceImpl implements BookService {

    //service需要依赖Dao
    private BookDao bookDao ;

    @Override
    public void save() {
        bookDao.save();
        System.out.println("service:添加书本..");
    }

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}

【第三步】配置service与dao之间的关系

在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. 创建Dao的对象,并且把该对象存储到了spring的容器中-->
    <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>



    <!--使用bean标签即可使用spring的ioc的功能,让spring创建BookServiceImpl这个类的对象
        id:  该对象在容器中唯一标示,名字可以随意,但是要确保唯一性。
        class: 通知spring帮我们创建制定类的对象,并且放入spring的容器中。
    -->
    <bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl">
          <!--给对象的bookDao的属性赋值
               name: 属性名,属性名是依赖setter方法的。
               ref: 引用,引用另外一个对象给该属性赋值。
          -->
        <property name="bookDao" ref="bookDao"/>
    </bean>

</beans>

图解演示

image-20230526161619419

  • <property name="" ref="引入对象的id值">标签
  • name:属性名,属性名依赖setter方法
  • ref: 引入的对象的id

3. Bean的基础配置

配置说明

image-20230526163301811

Bean别名配置

image-20230529143547907

<?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. 创建Dao的对象,并且把该对象存储到了spring的容器中-->
    <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>




    <!--name作用:给对象起一个别名,name与id的区别:id只能配置一个,name可以配置多个,name多个别名是使用,; 空格分隔-->
    <bean id="bookService" name="bookService1,bookService2,bookService4 bookService5" class="com.tyhxzy.service.impl.BookServiceImpl">
          <!--给对象的bookDao的属性赋值
               name: 属性名,属性名是依赖setter方法的。
               ref: 引用,引用另外一个对象给该属性赋值。
          -->
        <property name="bookDao" ref="bookDao"/>
    </bean>

</beans>
package com.tyhxzy.test;

import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {

    //测试:从spring的容器中获取对象
    @Test
    public void  testGetBean(){
        //        //1.创建spring的容器,读取配置文件 ,   ApplicationContext  是spring的容器的根接口。
        //ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2. 通过id从spring的容器中查找对象
        //BookService bookService = (BookService) context.getBean("bookService");

        //从容器中获取对象的时候,告诉容器对象的类型即可
        BookService bookService = context.getBean("bookService2", BookService.class);
        bookService.save();

        //3。关闭容器(以后不需要关闭的)
        context.close();
    }
}

image-20230529150515969

4. Bean作用范围配置

image-20230529150548091

扩展:scope的取值不仅仅只有singleton和prototype,还有request、session、application、 websocket ,表示创建出的对象放置在web容器(tomcat)对应的位置。比如:request表示保存到request域中。

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. 创建Dao的对象,并且把该对象存储到了spring的容器中-->
    <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>




    <!--name作用:给对象起一个别名,name与id的区别:id只能配置一个,name可以配置多个,name多个别名是使用,; 空格分隔
        scope作用: 指定对象的作用范围, 常用两种: singleton(单例,默认) , prototype(多例)
    -->
    <bean id="bookService" name="bookService1,bookService2,bookService4 bookService5"
          class="com.tyhxzy.service.impl.BookServiceImpl" scope="prototype">
          <!--给对象的bookDao的属性赋值
               name: 属性名,属性名是依赖setter方法的。
               ref: 引用,引用另外一个对象给该属性赋值。
          -->
        <property name="bookDao" ref="bookDao"/>
    </bean>

</beans>
package com.tyhxzy.test;

import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {

    //测试:从spring的容器中获取对象
    @Test
    public void  testGetBean(){
        //        //1.创建spring的容器,读取配置文件 ,   ApplicationContext  是spring的容器的根接口。
        //ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2. 通过id从spring的容器中查找对象
        //BookService bookService = (BookService) context.getBean("bookService");

        //从容器中获取对象的时候,告诉容器对象的类型即可
        BookService bookService1 = context.getBean("bookService2", BookService.class);
        BookService bookService2 = context.getBean("bookService2", BookService.class);

        System.out.println("两个对象是同一个吗?"+(bookService1==bookService2));

        //3。关闭容器(以后不需要关闭的)
        context.close();
    }
}

image-20230529150645268

最后给大家说明一下:在我们的实际开发当中,绝大部分的Bean是单例的,也就是说绝大部分Bean不需要配置scope属性。

  • 在<bean>标签上如何配置别名?
    • name属性可以配置
  • 那Bean的默认作用范围是什么?如何修改?
    • 单例,singleton.
    • scope="prototype|singleton"

四、Bean的实例化

Bean的实例化方式有几种

bean本质上就是对象,创建bean使用构造方法完成

1. 实例化Bean的三种方式

1.1 构造方法方式

package com.tyhxzy.dao.impl;

import com.tyhxzy.dao.BookDao;

public class BookDaoImpl implements BookDao {

    public BookDaoImpl() {
        System.out.println("BookDaoImpl的无参构造方法创建了....");
    }

    @Override
    public void save() {
        System.out.println("DAO:添加了图书..");
    }
}

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

    <!--方式一: 利用一个类的无参构造方法创建   以后最为常用的一种方式
        <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
    -->


</beans>

AppTest测试类

package com.tyhxzy.test;

import com.tyhxzy.dao.BookDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {

    //测试:从spring的容器中获取对象
    @Test
    public void  testGetBean(){
        //        //1.创建spring的容器,读取配置文件 ,   ApplicationContext  是spring的容器的根接口。
        //ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2. 通过id从spring的容器中查找对象
        //BookService bookService = (BookService) context.getBean("bookService");

        //从容器中获取对象的时候,告诉容器对象的类型即可
        BookDao bookDao = context.getBean("bookDao", BookDao.class);
        bookDao.save();

        //3。关闭容器(以后不需要关闭的)
        context.close();
    }
}

image-20230529152606199

注意:无参构造方法如果不存在,将抛出异常 BeanCreationException

1.2 静态工厂方式

BookFactoryBean工厂类

package com.tyhxzy.factory;

import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;

public class BookFactoryBean {

    /*
    静态的工厂方法
     */
    public static BookDao getBookDao(){
        System.out.println("静态工厂方法...");
        return new BookDaoImpl();
    }

}

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

    <!--方式一: 利用一个类的无参构造方法创建   以后最为常用的一种方式
        <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
    -->


    <!--方式二: 利用静态工厂方法创建对象
        id: 该对象在spring容器中id
        class: 静态工厂类的全类名
        factory-method: 静态工厂的方法名
    -->
    <bean id="bookDao" class="com.tyhxzy.factory.BookFactoryBean" factory-method="getBookDao"/>


</beans>

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

    <!--方式一: 利用一个类的无参构造方法创建   以后最为常用的一种方式
        <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
    -->


    <!--方式二: 利用静态工厂方法创建对象
        id: 该对象在spring容器中id
        class: 静态工厂类的全类名
        factory-method: 静态工厂的方法名
    -->
    <bean id="bookDao" class="com.tyhxzy.factory.BookFactoryBean" factory-method="getBookDao"/>


</beans>

AppTest测试类

package com.tyhxzy.test;

import com.tyhxzy.dao.BookDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {

    //测试:从spring的容器中获取对象
    @Test
    public void  testGetBean(){
        //        //1.创建spring的容器,读取配置文件 ,   ApplicationContext  是spring的容器的根接口。
        //ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2. 通过id从spring的容器中查找对象
        //BookService bookService = (BookService) context.getBean("bookService");

        //从容器中获取对象的时候,告诉容器对象的类型即可
        BookDao bookDao = context.getBean("bookDao", BookDao.class);
        bookDao.save();

        //3。关闭容器(以后不需要关闭的)
        context.close();
    }
}

运行结果

image-20230529153027404

1.3 实例工厂方法方式

BookFactoryBean工厂类

package com.tyhxzy.factory;

import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;

public class BookFactoryBean {

   

    /*
    非静态方法创建BookDaoImpl对象
     */
    public BookDao getBookDao2(){
        System.out.println("非静态工厂方法...");
        return new BookDaoImpl();
    }

}

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

    <!--方式一: 利用一个类的无参构造方法创建   以后最为常用的一种方式
        <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
    -->


    <!--方式二: 利用静态工厂方法创建对象
        id: 该对象在spring容器中id
        class: 静态工厂类的全类名
        factory-method: 静态工厂的方法名

    <bean id="bookDao" class="com.tyhxzy.factory.BookFactoryBean" factory-method="getBookDao"/>
     -->

    <!--方式三:非静态工厂方法创建对象
        步骤:
            1. 创建工厂类的对象
            2. 调用非静态方法创建制定类的对象
    -->

    <!--1. 创建工厂类的对象-->
    <bean id="bookFactoryBean" class="com.tyhxzy.factory.BookFactoryBean"/>

    <!--2. 调用非静态方法创建制定类的对象-->
    <bean id="bookDao" factory-bean="bookFactoryBean" factory-method="getBookDao2"/>
</beans>

image-20230529153132574

Bean的实例化方式有几种?

  • 无参的构造器
  • 工厂静态方法
  • 工厂非静态方法

五、Bean的生命周期

1. 生命周期相关概念介绍

  • 生命周期:从创建到消亡的完整过程
  • bean生命周期:bean从创建到销毁的整体过程
  • bean生命周期控制:在bean创建后到销毁前做一些事情

2.代码演示

提供生命周期控制方法

package com.tyhxzy.dao.impl;

import com.tyhxzy.dao.BookDao;

public class BookDaoImpl implements BookDao {

    /*
     如果BookDao对象创建的会调用init方法
     */
    public void init(){
        System.out.println("init方法被调用了,该类的对象已经被创建了..");
    }

    /*
        销毁该类的对象前调用方法

     */
    public void destroy(){
        System.out.println("destroy被调用了,马上就要销毁该类对象了...");
    }



    @Override
    public void save() {
        System.out.println("DAO:添加了图书..");
    }
}

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

    <!--
        init-method:  指定创建对象的时候调用的初始化方法的方法名
        destroy-method: 销毁对象前指定调用的方法
        默认情况spring使用的是饿汉单例设计模式,如果需要修改饿汉单例设计模式,可以lazy-init修改
            lazy-init="true" 懒汉模式
            lazy-init=false  饿汉模式 , 默认
    -->
    <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl" init-method="init" lazy-init="true" destroy-method="destroy" />

</beans>

测试类

package com.tyhxzy.test;

import com.tyhxzy.dao.BookDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*

    核心知识点:
        1. 默认情况spring使用的是饿汉单例设计模式,不是懒汉单例设计模式。在容器启动就创建该类的对象了。
        2. 容器关闭的时候才会销毁对象。


 */

public class AppTest {

    //测试:从spring的容器中获取对象
    @Test
    public void  testGetBean(){
        //        //1.创建spring的容器,读取配置文件 ,   ApplicationContext  是spring的容器的根接口。
        //ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
        ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("applicationContext.xml");
        context.close();
        //2. 通过id从spring的容器中查找对象
        //BookService bookService = (BookService) context.getBean("bookService");

        //从容器中获取对象的时候,告诉容器对象的类型即可
        BookDao bookDao = context.getBean("bookDao", BookDao.class);
        bookDao.save();

        //3。关闭容器(以后不需要关闭的)
        context.close();
      //  context.registerShutdownHook(); //这种方式是注册到jvm,通知jvm容器关闭的时候调用destroy方法。
    }
}

spring的bean对象的生命周期? 与什么周期相关的两个属性?
  • 创建spring容器的时候创建。
    
  • init-method , destory-method

六、依赖注入(DI配置)

1. 依赖注入

1.1 依赖注入的两种方式

  • setter注入
    简单类型(八种基础数据类型+stirng类型)
    引用类型(很常用)
  • 构造器注入
    简单类型
    引用类型

1.2 setter方式注入

问题导入

setter方式注入使用什么子标签?

引用类型

在bookService中使用ref注入bookDao

image-20230529155627068

<?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 id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>

    <!--依赖注入方式一: 利用setter方法,使用property标签注入-->
    <bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"/>
    </bean>

</beans>

简单类型

  1. 在BookDaoImpl中添加int connectionNumber
  2. 添加set方法
  3. 在配置文件中注入10
package com.tyhxzy.dao.impl;

import com.tyhxzy.dao.BookDao;

public class BookDaoImpl implements BookDao {

    private int connectionNumber;

    public void setConnectionNumber(int connectionNumber) {
        this.connectionNumber = connectionNumber;
    }

    @Override
    public void save() {
        System.out.println("DAO:添加了图书.."+connectionNumber);
    }
}

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

    <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl">
        <property name="connectionNumber" value="100"/>
    </bean>

    <!--依赖注入方式一: 利用setter方法,使用property标签注入-->
    <bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"/>
    </bean>

</beans>

测试类

package com.tyhxzy.test;

import com.tyhxzy.dao.BookDao;
import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {

    //测试:从spring的容器中获取对象
    @Test
    public void  testGetBean(){
       //1. 获取容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2. 从容器中获取bookDao对象
        BookDao bookDao = context.getBean("bookDao", BookDao.class);
        bookDao.save();
        //3 关闭容器
        context.close();
    }
}

1.3 构造方式注入

问题导入

构造方式注入使用什么子标签?

引用类型

  1. 给BookServiceImpl添加构造方法,参数是BookDao
  2. 在配置文件中给bookService中使用构造器注入bookDao

image-20230529160318203

BookServiceImpl, 添加构造方法

package com.tyhxzy.service.impl;

import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;
import com.tyhxzy.service.BookService;

public class BookServiceImpl implements BookService {

    //service需要依赖Dao
    private BookDao bookDao ;

    //一个带参的构造方法
    public BookServiceImpl(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    @Override
    public void save() {
        bookDao.save();
        System.out.println("service:添加书本..");
    }

    //删除setter方法
//    public void setBookDao(BookDao bookDao) {
//        this.bookDao = bookDao;
//    }
}

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

    <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl">
        <property name="connectionNumber" value="100"/>
    </bean>

    <!--依赖注入方式一: 利用setter方法,使用property标签注入
        <bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl">
            <property name="bookDao" ref="bookDao"/>
        </bean>
    -->

    <!--依赖注入方式二:利用构造方法给对象注入成员变量值-->
    <bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl">
       <!--
        index:  构造方法的参数的索引值,从0开始
        name: 构造方法的形参的名字

       <constructor-arg index="0" ref="bookDao"/>
       -->
        <constructor-arg name="bookDao" ref="bookDao"/>
    </bean>



</beans>

测试类

package com.tyhxzy.test;

import com.tyhxzy.dao.BookDao;
import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {

  
    @Test
    public void  testGetServiceBean(){
        //1. 获取容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2. 从容器中获取bookDao对象
        BookService bookService = context.getBean("bookService", BookService.class);
        bookService.save();
        //3 关闭容器
        context.close();
    }
}

简单类型

  1. 给BookDao添加整数类型的构造方法

    package com.tyhxzy.dao.impl;
    
    import com.tyhxzy.dao.BookDao;
    
    

public class BookDaoImpl implements BookDao {

private int connectionNumber;

private  String databaseName;

/* public void setConnectionNumber(int connectionNumber) {
this.connectionNumber = connectionNumber;
}*/

public BookDaoImpl(int connectionNumber) {
    this.connectionNumber = connectionNumber;
   }

public BookDaoImpl(int connectionNumber, String databaseName) {
       this.connectionNumber = connectionNumber;
       this.databaseName = databaseName;
   }

@Override
   public void save() {
       System.out.println("DAO:添加了图书.."+connectionNumber+" 数据库的名称:"+ databaseName);
   }

}


1. 使用配置通过构造器给BookDao注入属性值

   ```xml
    <!--利用构造器方式初始化成员变量-->
       <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl">
           <constructor-arg name="connectionNumber" value="10"/>
           <constructor-arg name="databaseName" value="spring_db"/>
       </bean>

参数适配【了解】

  1. 按类型的方式匹配
  2. 按位置的方式匹配

步骤

  1. 添加新的成员变量:String databaseName

  2. 创建2个参数的构造方法

  3. 生成toString方法

    package com.tyhxzy.dao.impl;
    
    import com.tyhxzy.dao.BookDao;
    
    /**
     * 书籍DAO的实现类
     */
    public class BookDaoImpl implements BookDao {
    
        //成员变量
        private int connectionNumber;
        private String databaseName;
    
        //无参的构造方法
        public BookDaoImpl() {
        }
    
        //1个参数的构造方法
        public BookDaoImpl(int connectionNumber) {
            this.connectionNumber = connectionNumber;
        }
    
        //2个参数的构造方法
        public BookDaoImpl(int connectionNumber, String databaseName) {
            this.connectionNumber = connectionNumber;
            this.databaseName = databaseName;
        }
    
        @Override
        public String toString() {
            return "BookDaoImpl{" +
                    "connectionNumber=" + connectionNumber +
                    ", databaseName='" + databaseName + '\'' +
                    '}';
        }
    }
    
  4. 分别使用类型匹配和位置匹配的方式注入值

image-20230529160408405

2. 依赖自动装配【理解】

问题导入

如何配置按照类型自动装配?

2.1 自动装配概念

  • IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
  • 自动装配方式
    • 按名称
    • 按构造方法
    • 不启用自动装配

2.2 自动装配类型

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


    <!--利用构造器方式初始化成员变量-->
    <bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl">
        <constructor-arg name="connectionNumber" value="10"/>
        <constructor-arg name="databaseName" value="spring_db"/>
    </bean>

    <!--autowire: 创建该类对象的时候成员变量的初始化可以根据类型赋值,自动注入是依赖setter方法
        创建BookServiceImpl对象的时候发现,该类有一个成员变量需要BookDao,那么spring就会自动从容器中去
        查找是否有BookDao这种类型的对象。
    -->
    <bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl" autowire="byType"/>



</beans>
package com.tyhxzy.service.impl;

import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;
import com.tyhxzy.service.BookService;

public class BookServiceImpl implements BookService {

    //service需要依赖Dao
    private BookDao bookDao ;

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    @Override
    public void save() {
        bookDao.save();
        System.out.println("service:添加书本..");
    }

}

测试类

package com.tyhxzy.test;

import com.tyhxzy.dao.BookDao;
import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {


    @Test
    public void  testGetServiceBean(){
        //1. 获取容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2. 从容器中获取bookDao对象
        BookService bookService = context.getBean("bookService", BookService.class);
        bookService.save();
        //3 关闭容器
        context.close();
    }
}

小结

依赖注入有几种方式,分别对应的是哪个标签或者属性

- 通过setter方法注入    property标签
  - 构造方法注入     constructor-arg

3. 集合注入

3.1 注入数组类型数据

<property name="array">
    <array>
        <value>100</value>
        <value>200</value>
        <value>300</value>
    </array>
</property>

3.2 注入List类型数据

<property name="list">
    <list>
        <value>itcast</value>
        <value>tyhxzy</value>
        <value>boxuegu</value>
        <value>chuanzhihui</value>
    </list>
</property>

3.3 注入Set类型数据

<property name="set">
    <set>
        <value>itcast</value>
        <value>tyhxzy</value>
        <value>boxuegu</value>
        <value>boxuegu</value>
    </set>
</property>

3.4 注入Map类型数据

<property name="map">
    <map>
        <entry key="country" value="china"/>
        <entry key="province" value="henan"/>
        <entry key="city" value="kaifeng"/>
    </map>
</property>

3.5 注入Properties类型数据

<property name="properties">
    <props>
        <prop key="country">china</prop>
        <prop key="province">henan</prop>
        <prop key="city">kaifeng</prop>
    </props>
</property>

说明:property标签表示setter方式注入,构造方式注入constructor-arg标签内部也可以写<array>、<list>、<set>、<map>、<props>标签

小结:

数组: array

list:   list

set:  set

map:  map

properties: props

标签:容器,tyhxzy,Spring,context,import,com,public
From: https://www.cnblogs.com/YxinHaaa/p/17441661.html

相关文章

  • springmvc请求处理流程分析入口
    1从浏览器发起请求,根据servlet原理会进入到service方法2根据HttpServlet实习了service方法,所以进入到HttpServlet的service方法3service方法根据post和get的请求方式,选择进入doGet和doPost方法4FrameworkServlet重写了doGet和doPost方法,又调用了processRequest5最后调用......
  • 使用H2数据库搭建springboot应用
    h2数据库有2中模型,一种是嵌入式,一种是服务端。嵌入式时,我们多个配置同一个地址就可以访问同一个数据集,服务端需要额外开启服务,再通过ip端口访问。这里我们介绍下怎么在springboot项目下开启服务端模式。1、在springboot应准备就绪后启动h2服务publicclassH2Serverimplements......
  • SpringBoot 项目 返回时间 日期、格式不正确 解决办法
    https://blog.csdn.net/rain67/article/details/127200263 SpringBoot项目返回时间格式不正确解决办法1、遇到问题2、解决方法(1)问题所在(2)如何解决(3)效果SpringBoot项目返回时间格式不正确解决办法  今天做一个SpringBoot+Vue的一个练习项目,想要搞一个创建该账号的时间,......
  • SpringBoot自动配置原理
    在SpringBoot项目中的引导类上有一个注解@SpringBootApplication,这个注解是对三个注解进行了封装,分别是:@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan其中@EnableAutoConfiguration是实现自动化配置的核心注解。该注解通过@Import注解导入对应的配......
  • SpringMVC的执行流程
    SpringMVC有四大组件:(1)前端控制器(DispatcherServlet)(2)处理器映射器(HandlerMapping)(3)处理器适配器(HandlerAdapter)(4)视图解析器(ViewReslover)执行流程:(1)前端发送请求到前端控制器(DispatcherServlet)。(2)前端控制器调用处理器映射器解析出Handler返回给前端控制器。(3)前端控制器调用处......
  • Spring事务的实现方式
    Spring事务有两种实现方式:(1)编程式事务:自己手动控制开启事务、提交事务、回滚事务。优点:编程式事务可以根据业务逻辑和数据操作的复杂度进行灵活的控制和处理,保证数据的一致性和完整性;使用编程式事务时,可以控制每个事务的大小和影响范围,因此在大型系统需求变化频繁的情况下很有......
  • SpringMVC学习系列(9) 之 实现注解式权限验证
    对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在SpringMVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现。但借助于SpringMVC中的action拦截器我们可以实现注解式的权限验证。一.首先介绍一下action拦截器:HandlerInterceptor是Sp......
  • SpringMVC学习系列(8) 之 国际化
    在系列(7)中我们讲了数据的格式化显示,Spring在做格式化展示的时候已经做了国际化处理,那么如何将我们网站的其它内容(如菜单、标题等)做国际化处理呢?这就是本篇要将的内容—>国际化。一.基于浏览器请求的国际化实现:首先配置我们项目的springservlet-config.xml文件添加的内容如下:<bean......
  • SpringMVC学习系列(6) 之 数据验证
    在系列(4)、(5)中我们展示了如何绑定数据,绑定完数据之后如何确保我们得到的数据的正确性?这就是我们本篇要说的内容—>数据验证。这里我们采用Hibernate-validator来进行验证,Hibernate-validator实现了JSR-303验证框架支持注解风格的验证。首先我们要到http://hibernate.org/validator......
  • SpringMVC学习系列(7) 之 格式化显示
    在系列(6)中我们介绍了如何验证提交的数据的正确性,当数据验证通过后就会被我们保存起来。保存的数据会用于以后的展示,这才是保存的价值。那么在展示的时候如何按照要求显示?(比如:小数保留一定的位数,日期按指定的格式等)。这就是本篇要说的内容—>格式化显示。从Spring3.X开始,Spring提供......