Spring基础(XML配置形式)

1 Spring 能做什么?

1)官方网站
Home
2)个人总结

  • Spring 的核心是 IoC(控制反转)和 AOP(面向切面编程),SpringMVC 是需要依赖 Spring 的基础;
  • SpringMVC 其实简化了 Web 开发,但是,实际开发中依然需要配置很多东西,可以用 xml 或者 java 代码配置,这无疑是一个繁重的操作,因此 SpringBoot 诞生了,简化 SpringWeb 的配置开发;
  • Spring 旨在简化 J2EE 企业应用程序开发。Spring Boot 旨在简化 Spring 开发(减少配置文件,开箱即用!)

3)Spring 学习准备工作

Maven 仓库spring-context

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.2.10.RELEASE</version>
</dependency>

2 IoC 思想

2.1 什么是控制反转?

主要是为了降低程序的耦合度,在之前书写 JavaWeb 项目的时候,我们经常需要自己手动 new 一个 service 对象的实现类等等操作,这会提高代码的耦合度,在大型项目中这是不利于我们维护项目的。Spring 中引入 IoC 控制反转的概念,简单来讲就是不用手动 new 具体的实现类对象,Spring 会有一个称为 IoC 容器的东西,帮我们维护这这些实例对象,当我们需要使用的时候,Spring 将这个示例对象直接给我们即可。
Spring 中的 IoC 容器是对 IoC 思想的具体实现,不是只有在 Spring 中特有的。
**控制:**对象的实例化、管理的权力;
**反转:**将控制权力交给外部;
代码自己不会实例化对象,而是将实例化对象的权力交给 IoC 容器,当需要对象的时候,只需要向 IoC 容器索要即可,IoC 容器会维护一堆相应的对象;
Spring 中的 IoC 容器是 IoC 思想的具体实现,其实 IoC 容器就是一个 Map(Key,Value)的形式,容器中存放这各种各样的 bean 对象;

2.2 代码体验

1)通过配置 xml 文件实现 bean 对象的控制反转

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

    <!-- 使用xml配置bean对象 -->
    <!--
        id: 表示唯一识别的名字
        class: 具体的类的全类名
    -->
    <bean id="bookDao" class="cn.edu.njust.dao.impl.BookDaoImpl"/>
    <bean id="bookService" class="cn.edu.njust.service.impl.BookServiceImpl"/>
</beans>
package cn.edu.njust;

import cn.edu.njust.dao.BookDao;
import cn.edu.njust.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 体验IoC容器如何获取Bean对象
 */
public class TestDemo01 {
    public static void main(String[] args) {
        // 获取IoC容器对象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        /*
        * 使用这个IoC对象获取我们的Bean对象
        * getBean: 根据xml文件中的id属性来获取bean对象
        * */
        // 1.获取BookDao
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();

        System.out.println("------------------------");

        // 2.获取BookService对象
        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}

3 Spring 中对 bean 对象的管理

Spring 中 bean 对象就是 IoC 容器中管理的对象,任何可以 new 出来的实例都可以作为 bean 对象管理;不仅是自己写的类可以使用 bean 对象管理,引入的第三方的实体类也可以交给 IoC 容器进行管理,比如引入数据库连接池 Druid 或者 C3P0 等等;

Spring 中使用 IoC 容器将 bean 对象交给容器管理,开发者不需要自己手动 new 对象实例,这样可以降低程序的耦合度,那 IoC 容器是如何帮我们实例化对象的呢?
Spring 的实例化有几种方式,主要是:构造器静态工厂实例化工厂

3.1 通过构造器实例化 bean

简单的说,就是虽然我们不手动的 new 对象实例,并且通过这种 xml 文件配置的方式将 new 实例的工作交给 Spring 的 IoC 容器。

3.1.1 默认使用无参构造

<bean id="userDao" class="cn.edu.njust.dao.impl.UserDaoImpl"/>
<bean id="orderDao" class="cn.edu.njust.dao.impl.OrderDaoImpl"/>

类似这样使用标签配置的 bean 对象,Spring 底层使用默认的无参构造器来实例化 bean 对象;
若是想要检验是否调用了午餐构造,可以自己添加无参构造器并输出日志查看验证。

3.1.2 使用有参构造

<bean id="orderService" class="cn.edu.njust.service.impl.OrderServiceImpl">
  <!-- 使用 constructor-arg 标签配置简单数据类型的注入 -->
  <constructor-arg name="name" value="TIANSU"/>
  <constructor-arg name="num" value="1"/>
</bean>

除了无参构造,还可以使用有参构造,当然,此时必须保证class指定的类中有相应的构造器;
参数使用constructor-arg来指定;

3.2 通过静态工厂实例化 bean

主要是和传统的使用静态工厂实例化对象方式对接。
(1)构造一个静态工厂

public class UserDaoFactory {
    public static UserDao getUserDao() {
        return new UserDaoImpl();
    }
}

(2)配置 bean 标签

<!-- 使用静态工程实例化bean -->
<bean id="userDao" class="cn.edu.njust.factory.UserDaoFactory" factory-method="getUserDao"/>
  • bean 标签中 class 属性指定的类是这个静态工厂类
  • 使用 factory-method 属性指定构造实例化对象的静态方法;

3.3 通过实例化工厂实例化 bean

主要是和传统的使用实例化工厂实例化对象的方式对接。
(1)实例化工厂

public class UserServiceFactory {
    public UserService getUserServiceDao() {
        return new UserServiceImpl();
    }
}

(2)配置 bean 标签

<!-- 使用示例工程实例化bean -->
<!-- 使用这种方式,首先需要先制造工厂的bean对象 -->
<bean id="userServiceFactory" class="cn.edu.njust.factory.UserServiceFactory"/>
<!-- 在获取bean对象 -->
<bean id="userService" factory-bean="userServiceFactory" factory-method="getUserServiceDao"/>
  • 首先配置一个实例工厂的 bean 对象;
  • 其次配置目的 bean 对象的 bean 标签:标签中使用 factory-bean 指定实例工厂的 bean 对象,属性值是实例工厂 bean 对象的 id 属性;同时需要使用 factory-method 属性指定获取目的实例化对象的方法;

(3)总结:这种方式中,可以看到实例化工厂的 bean 对象就是一个“中间件”,其作用就是为了配置目的 bean;因此 Spring 提供了另外一种实例化工厂获取 bean 对象的方式;

3.4 通过实例化工厂实例化 bean(pro)

(1)实现 FactoryBean

package cn.edu.njust.factory;

import cn.edu.njust.service.UserService;
import cn.edu.njust.service.impl.UserServiceImpl;
import org.springframework.beans.factory.FactoryBean;

/**
 * -- coding: UTF-8 -- *
 *
 * @author wangs
 * @date 2023/11/9 20:30
 * @description 实例化工厂的升级版
 */
public class UserServiceFactoryBean implements FactoryBean<UserService> {
    /**
     * 代替原始实例化对象中的工厂方法
     * @return
     * @throws Exception
     */
    @Override
    public UserService getObject() throws Exception {
        return new UserServiceImpl();
    }

    /**
     * 获取对象的类型
     * @return
     */
    @Override
    public Class<?> getObjectType() {
        return UserService.class;
    }
}

  • 实现 FactoryBean,指定需要实例化的对象;
  • 实现 getObject 方法,返回实例化对象
  • 实现 getObjectType 方法,返回实例化对象的 class 文件;

(2)配置 bean 标签

<!-- 实例化工厂变种方式 -->
<bean id="userService" class="cn.edu.njust.factory.UserServiceFactoryBean"/>

只需要正常配置即可,id 属性指明需要维护的 bean 对象,class 属性直接指向 FactoryBean 的实现类;

4 依赖注入

4.1 什么是依赖注入 DI?

在容器中建立 bean 和 bean 之间的关系的过程,称之为依赖注入。IoC 为我们实现控制反转,如 JavaWeb 中,service 层需要使用到 dao/mapper 层的 bean 对象,这两个对象之间存在着某种联系,DI 就是根据这样的特性来将 IoC 容器中的 bean 对象自动的关联起来。方便使用。

Spring 使用 IoC 和 DI 最终实现了充分解耦

1) 依赖注入实例:

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

    <!-- 使用xml配置bean对象 -->
    <!--
        id: 表示唯一识别的名字
        class: 具体的类的全类名
        name: 配置bean的别名,可以配置多个
        scope: 配置这个类是单例模式还是非单例模式
            singleton: 单例,默认值
            prototype: 非单例
    -->
    <bean id="bookDao" name="bookDao2,dao" class="cn.edu.njust.dao.impl.BookDaoImpl" scope="singleton"/>

    <!-- 配置依赖 -->
    <!--
        因为在 BookService 中使用到了 BookDao 的实例对象,所以在 BookService 中配置
    -->
    <bean id="bookService" class="cn.edu.njust.service.impl.BookServiceImpl">
        <!-- 属性说明:
            1.name: 这个属性对应的是具体示例的名称,在此处,BookService中的示例名称为 bookDao
            2.ref: 关联bean对象,此处的bookDao指的是本文件中配置的 id 为 bookDao 的bean对象
        -->
        <property name="bookDao" ref="bookDao"/>
    </bean>
</beans>

2)Spring 中 DI 注入的几种方式:setter 注入、构造器注入、简单数据类型注入、集合类型数据注入

4.2 setter 注入

(1)示例实现类

package cn.edu.njust.service.impl;

import cn.edu.njust.dao.OrderDao;
import cn.edu.njust.dao.UserDao;
import cn.edu.njust.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    private OrderDao orderDao;

    public UserServiceImpl() {
    }

    /**
     * 提供给构造器注入的方式使用
     * @param orderDao
     */
    public UserServiceImpl(OrderDao orderDao) {
        this.orderDao = orderDao;
    }

    @Override
    public void run() {
        System.out.println("UserService is running...");
        userDao.run();
    }

    @Override
    public void ordered() {
        orderDao.run();
    }

    /**
     * 构造器,提供给setter注入使用
     * @param userDao
     */
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

(2)bean 标签配置

<!-- 配置要使用到的 bean 对象 -->
<bean id="userDao" class="cn.edu.njust.dao.impl.UserDaoImpl"/>
<bean id="userService" class="cn.edu.njust.service.impl.UserServiceImpl">
  <!-- 使用 property 标签配置 setter 注入 -->
  <property name="userDao" ref="userDao"/>
</bean>
  • 使用 property 标签指定需要注入的 bean 对象
  • 必须要有相应的 bean 对象的 setter

4.3 构造器注入

构造器注入主要就是在相应发类中先提供对应参数的构造器,然后在 xml 配置文件中使用 constructor-arg 标签配置

<!-- 配置要使用到的 bean 对象 -->
<bean id="userDao" class="cn.edu.njust.dao.impl.UserDaoImpl"/>
<bean id="orderDao" class="cn.edu.njust.dao.impl.OrderDaoImpl"/>
<bean id="userService" class="cn.edu.njust.service.impl.UserServiceImpl">
  <!-- 使用 property 标签配置 setter 注入 -->
  <property name="userDao" ref="userDao"/>
  <!-- 使用 constructor-arg 标签配置构造器注入-->
  <constructor-arg name="orderDao" ref="orderDao"/>
</bean>
  • 使用 constructor-arg 标签指定注入的参数;
  • 必须提供相应的构造器;

4.4 简单数据类型注入

简单数据类型的注入和 bean 对象的注入方式极为相似,区别就是 bean 对象使用 ref 关联 bean 的实例,而简单数据类型使用 vlaue 赋值。

<bean id="orderService" class="cn.edu.njust.service.impl.OrderServiceImpl">
  <!-- 使用 constructor-arg 标签配置简单数据类型的注入 -->
  <constructor-arg name="name" value="TIANSU"/>
  <constructor-arg name="num" value="1"/>
</bean>

4.5 bean 对象自动配置

在 xml 中程序员根据各个 bean 之间的依赖关系而先设定一些配置,是比较麻烦的操作,Spring 为提供了一种便捷的操作方式,使用自动配置,IoC 容器会按照一定的规则,当需要使用某个 bean 对象的时候,自己在容器中寻找,并建立依赖关系。
主要的自动配置方式有:按类型自动配置、按名称自动配置。

4.5.1 按类型自动装配

<!--
自动配置
	ByType: 按类型自动配置中待配置的bean对象的id还可以省略
	ByName: 按名称自动配置中,待配置的bean对象id不能省略
-->
<bean id="bookDao" class="cn.edu.njust.dao.impl.BookDaoImpl"/>
<!--    <bean class="cn.edu.njust.dao.impl.BookDaoImpl"/>-->
<bean id="bookService" class="cn.edu.njust.service.impl.BookServiceImpl" autowire="byType"/>

  • 使用 autowire 属性指定注入的方式
  • byType:按类型自动配置,IoC 容器会根据需要的 bean 对象的类型,在容器中寻找,然后建立依赖;
  • 这种方式中,别配置的 bean 对象的 id 属性可以省略,如上面的<bean id="bookDao" class="cn.edu.njust.dao.impl.BookDaoImpl"/>中可以省略 id 属性;
  • 如果 IoC 容器中某一类型的 bean 对象有多个,会出现错误,此时可以使用按名称自动配置解决;

4.5.2 按名称自动配置

<!--
自动配置
ByType: 按类型自动配置中待配置的bean对象的id还可以省略
ByName: 按名称自动配置中,待配置的bean对象id不能省略
-->
<bean id="bookDao" class="cn.edu.njust.dao.impl.BookDaoImpl"/>
<!--    <bean class="cn.edu.njust.dao.impl.BookDaoImpl"/>-->
<bean id="bookService" class="cn.edu.njust.service.impl.BookServiceImpl" autowire="byName"/>

  • 这种方式被配置的 bean 对象必须指明 id 属性,否则报错

4.5.3 自动装配与其他装配方式的注意事项

1)按类型自动配置:
1.1)自动配置的 bean 对象的 setter 必须存在;
1.2)配置文件中存在多个同类型的 bean 对象,即 IoC 容器中同一种类型的 bean 对象有多个,就会报错;
1.3)被注入的 bean 对象必须在配置文件中声明;
1.4)被注入的 bean 对象的 id 属性可以省略;

2)按名称自动配置:
2.1)被注入 bean 对象必须在配置文件中声明;
2.2)被注入的 bean 对象的 id 不能省略;
2.3)被注入对象的 setter 必须按规矩生成;因为按名称注入的方式是将 setter 方法的 set 之后的名称首字母小写后作为注入对象的名称,不统一的情况下很可能出错;
2.4)这种方式支持一个 IoC 容器中存在多个同种类型的 bean 对象。

注意:自动配置的优先级低于 setter 注入和构造器注入,当这些方式同时存在的时候,自动配置失效。

5 知识汇总

5.1 标签汇总



5.2 常用方法

**方法原型 **说明
Object getBean(String var1) throws BeansException根据 xml 文件中 id 属性名称获取 bean 对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拜见老天師

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值