[SSM]Spring5

Posted Spring-_-Bear

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SSM]Spring5相关的知识,希望对你有一定的参考价值。

Spring5

一、IOC(控制反转)

1. Spring5 概述及入门案例

  1. Spring 是轻量级的开源的 JavaEE 框架,可以解决企业开发的复杂性。Spring 有两个核心部分 IOC 和 Aop
  2. IOC(Inversion of Control):控制反转,把创建对象的过程交给 Spring 进行管理
  3. Aop(Aspect Oriented Programming):面向切面,不修改源代码的情况下增强功能
  4. Spring 特点:方便解耦、简化开发;Aop 编程的支持;方便程序的测试;方便集成其它框架;降低 JavaEE API 的使用难度;方便进行事务操作
  1. Spring5 组成示意图:


6. Spring 快速入门案例:

  1. Spring 下载网址:https://repo.spring.io/ui/native/release/org/springframework/spring/
  2. 在 src 目录下新建 bean 类的 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="user" class="com.bear.spring.bean.User"/>
</beans>
  1. 在 Test 类中加载配置文件,并创建类对象,调用类方法
@Test
public void print() 
    // 加载 Spring 配置文件
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("user_bean.xml");
    // 创建对象
    User user = context.getBean("user", User.class);
    System.out.println(user);
    user.print();

2. IOC 概念及原理

  1. IOC(Inversion of Control)控制反转,是面向对象编程中的一种设计原则,用来降低代码间的耦合度。把对象创建及对象之间的调用过程都交给 Spring 进行管理
  2. IOC 底层使用的技术:xml 解析、工厂设计模式、反射
  3. IOC 容器管理 bean 实例过程:在 xml 文件中配置 bean 类的路径;通过 xml 解析技术获取 bean 类的全路径;利用反射技术创建类的实例对象
  4. Spring 提供 IOC 容器的两种方式:BeanFactory:IOC 容器基本实现,Spring 底层使用,一般情况下不建议开发人员不使用,特点是加载配置文件的时候不会创建对象,在获取或使用对象的时候才创建对象;ApplicationContextBeanFactory 的子接口,提供了比 BeanFactory 更多的功能,特点是加载配置文件的同时创建对象
  5. 使用 IOC 时依赖的 Spring 核心 jar 包:spring-expression-5.2.6.RELEASE.jarspring-core-5.2.6.RELEASE.jarspring-context-5.2.6.RELEASE.jarspring-beans-5.2.6.RELEASE.jarcommons-logging-1.1.1.jar

3. 创建对象和 setter 注入属性

  1. 创建对象时默认执行无参构造器
  2. DI(Dependency Injection)依赖注入,是 IOC 的一种具体实现,Spring 中支持 setter 方法和有参构造器注入属性
  3. bean 标签中使用 property 标签设置 key-value 完成属性注入
<bean id="user" class="com.bear.spring.bean.User">
    <property name="username" value="Spring-_-Bear"/>
    <property name="password" value="123"/>
</bean>

4. 有参构造器注入属性

<bean id="user" class="com.bear.spring.bean.User">
    <constructor-arg name="username" value="Spring-_-Bear"/>
    <constructor-arg name="password" value="Spring-_-Bear"/>
</bean>

5. p 名称空间注入属性

<bean id="user" class="com.bear.spring.bean.User" p:username="Spring-_-Bear" p:password="123"/>

6. 注入空值和特殊符号

<!-- 注入空值 -->
<bean id="book" class="com.bear.spring.bean.Book">
    <property name="title">
        <null/>
    </property>
</bean>

<!-- 注入特殊符号方式一:将特殊符号写入到 xml 的 CDATA 区 -->
<bean id="book" class="com.bear.spring.bean.Book">
    <property name="title">
        <value><![CDATA[<<浪潮之巅>>]]></value>
    </property>
</bean>
<!-- 注入特殊符号方式二:使用特殊符号转义符:&gt;、&lt; -->
<bean id="book" class="com.bear.spring.bean.Book">
    <property name="title" value="&lt;&lt;浪潮之巅&gt;&gt;"/>
</bean>

7. 注入外部 bean

<bean id="userDaoImpl" class="com.bear.spring.dao.impl.UserDaoImpl"/>
<bean id="userServ  ice" class="com.bear.spring.service.impl.UserServiceImpl">
    <!-- 在 service 中注入 dao -->
    <property name="userDao" ref="userDaoImpl"/>
</bean>

8. 注入内部 bean 和级联赋值

<!-- 内部 bean 注入 -->
<bean id="student" class="com.bear.spring.pojo.Student">
    <constructor-arg name="id" value="1"/>
    <constructor-arg name="name" value="Spring-_-Bear"/>
    <property name="className">
        <bean class="com.bear.spring.pojo.Class">
            <property name="name" value="高三一班"/>
        </bean>
    </property>
</bean>

<!-- 级联赋值 1 -->
<bean id="student" class="com.bear.spring.pojo.Student">
    <property name="id" value="1"/>
    <property name="name" value="李春雄"/>
    <property name="className" ref="class"/>
</bean>
<bean id="class" class="com.bear.spring.pojo.Class">
    <property name="name" value="高三一班"/>
</bean>

<!-- 级联赋值 2 -->
<bean id="student" class="com.bear.spring.pojo.Student">
    <property name="id" value="1"/>
    <property name="name" value="李春雄"/>
    <property name="gradeName" ref="grade"/>
    <!-- 需在 Student 类中生成 Grade 类的 getter 方法 -->
    <!-- 设置 Student 类中 Grade 对象的 name 属性值 -->
    <property name="gradeName.name" value="高三"/>
</bean>
<bean id="grade" class="com.bear.spring.pojo.Grade"/>

9. 注入数组、List、Map、Set

<bean id="student" class="com.bear.spring.pojo.Student">
    <!-- 注入数组类型 -->
    <property name="courses">
        <array>
            <value>Java</value>
            <value>Cpp</value>
        </array>
    </property>
    <!-- 注入 List 集合类型 -->
    <property name="courseList">
        <list>
            <value>Database</value>
            <value>mysql</value>
        </list>
    </property>
    <!-- 注入 Map 集合类型 -->
    <property name="map">
        <map>
            <entry key="1" value="JDK"/>
            <entry key="2" value="JVM"/>
        </map>
    </property>
    <!-- 注入 Set 集合类型 -->
    <property name="set">
        <set>
            <value>1</value>
            <value>2</value>
        </set>
    </property>
</bean>

10. 注入集合(集合中注入其它对象)

<bean id="student" class="com.bear.spring.pojo.Student">
    <!-- List 集合中注入其它对象 -->
    <property name="courseList">
        <list>
            <ref bean="course1"/>
            <ref bean="course2"/>
        </list>
    </property>
</bean>

<bean id="course1" class="com.bear.spring.pojo.Course">
    <property name="name" value="Spring"/>
</bean>
<bean id="course2" class="com.bear.spring.pojo.Course">
    <property name="name" value="MyBatis"/>
</bean>

11. 抽取公共注入工具

抽取公共注入:

  1. 引入 util 名称空间
  2. 抽取 list 注入工具
  3. 在其它 bean 中使用 util 完成注入
<bean id="course1" class="com.bear.spring.pojo.Course">
    <property name="name" value="Spring"/>
</bean>
<bean id="course2" class="com.bear.spring.pojo.Course">
    <property name="name" value="MyBatis"/>
</bean>
<!-- 抽取为 list 注入工具,供多个 bean 使用 -->
<util:list id="courseList">
    <ref bean="course1"/>
    <ref bean="course2"/>
</util:list>
<bean id="student" class="com.bear.spring.pojo.Student">
	<!-- 多个 bean 中可引用 courseList 公共注入工具 -->
    <property name="courseList" ref="courseList"/>
</bean>

12. 工厂 bean

  1. 普通 bean:在配置文件中定义的 bean 的类型就是返回的类型
  2. 工厂 bean:实际返回的 bean 类型可以和配置文件中声明的类型不一致
  3. 工厂 bean 的使用方式:自定义类实现 FactoryBean 接口,在实现的 getObject 方法中根据需要返回具体的 bean 类型,此时在 xml 配置文件中声明的类型与实际返回的类型可以不一致
/**
 * @author Spring-_-Bear
 * @datetime 2022/4/4 22:27
 */
public class Bean implements FactoryBean<Course> 
    @Override
    public boolean isSingleton() 
        return FactoryBean.super.isSingleton();
    

    @Override
    public Course getObject() 
        Course course = new Course();
        course.setName("Spring5");
        return course;
    

    @Override
    public Class<?> getObjectType() 
        return null;
    

13. bean 作用域

  1. Spring 中默认创建的对象为单实例,可以通过配置 scope 属性设置多实例 (每次获取对象时都创建新的对象)scope="singleton" 为默认值
  2. 单实例对象在加载配置文件的时候就会创建,而多实例对象只有在获取对象的时候才创建
<!-- 配置 bean 多实例 -->
<bean id="student" class="com.bear.spring.pojo.Student" scope="prototype">
    <property name="courseList" ref="courseList"/>
</bean>

14. bean 生命周期

  1. 通过无参构造器创建 bean 实例
  2. 调用 setter 方法为 bean 的字段赋值和完成对其它 bean 的引用
  3. 调用 bean 的初始化方法(初始化方法需要进行配置:在 bean 标签中使用 init-method 属性调用自定义的初始化方法)
  4. 获取到 bean 对象,正常使用 bean
  5. 当容器关闭的时候,调用 bean 的销毁方法(销毁方法需要进行配置:在 bean 标签中使用 destory-method 属性调用自定义的销毁方法,当使用 context.close(); 销毁 bean 对象时此自定义销毁方法会被调用)
  6. 若创建了后置处理器(自定义类实现 BeanPostProcessor 接口,在 xml 配置文件中使用 bean 标签进行配置此实现类的 bean),在第三步之后会把 bean 实例传递给后置处理器的 postProcessBeforeInitialization 方法,可在此方法中对初始化后的 bean 进行进一步处理,Spring 会为当前配置文件中的所有 bean 实例都添加后置处理器
/**
 * @author Spring-_-Bear
 * @datetime 2022/4/5 16:40
 */
public class BeanPost implements BeanPostProcessor 
   @Override
   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException 
      return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
   

   @Override
   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException 
      return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
   

15. 自动装配

自动装配:根据指定装配规则(属性名称或属性类型),Spring 自动将匹配的属性值进行注入,使用 bean 标签中的 autowire 属性指定自动装配,autowire 属性有两个常用的值:

  1. byName:根据属性名进行注入,注入值 bean 的 id 值和类属性名称一致
  2. byType:根据类型注入(要求配置文件中有且仅有一个该类型的 bean 实例)
<!-- 自动装配 -->
<bean id="student" class="com.bear.spring.pojo.Student" autowire="byName"/>
<bean id="grade" class="com.bear.spring.pojo.Grade">
    <property name="name" value="高三"/>
以上是关于[SSM]Spring5的主要内容,如果未能解决你的问题,请参考以下文章