SSM笔记(原Spring Framework笔记)

为什么要学Spring框架

  • Spring技术是JavaEE开发必备技能,企业开发技术选型命中率>90%
  • 专业角度:
    • 简化开发,降低企业级开发的复杂性
    • 框架整合,高效整合其他技术,提高企业级应用开发与运行效率

怎么学?

  • 学习Spring框架设计思想
  • 学习基础操作,思考操作与思想间的联系

初识Spring

  • 官网:spring.io
  • Spring发展到今天已经形成一种开发的生态圈,Spring提供了若干个项目,每个项目用于完成特定的功能

SpringFrame系统架构

Spring Framework是Spring生态圈中最基础的项目,是其他项目的根基

spring4架构图

  • Data Access:数据访问
  • Data Integration:数据集成
  • Web:Web开发
  • AOP:面向切面编程
  • Aspects:AOP思想实现
  • Core Container:核心容器
  • Test:单元测试与集成测试

核心概念

Ioc/DI
Ioc容器
Bean

  • 代码书写现状:耦合度偏高
  • 解决方案:使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象
  • Ioc(控制反转):对象的创建控制权由程序转移到外部,这种思想称为控制反转
  • Spring技术对Ioc思想进行了实现:
    • Spring提供了一个容器,称为Ioc容器,用来充当Ioc思想中的**“外部”**。
    • Ioc容器负责对象的创建,初始化等一系列工作,被创建或被管理的对象在Ioc容器中统称为Bean
  • DI(依赖注入):在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
  • 目标:充分解耦
    -使用Ioc容器管理bean(Ioc)
    -在Ioc容器内将有依赖关系的bean进行关系绑定(DI)
    -最终效果:使用对象时不仅可以直接从Ioc容器中获取,并且获取到的bean已经绑定了所有的依赖关系

IoC入门案例思路分析
1.管理什么?(Service与Dao)
2.如何将被管理的对象告知IoC容器?(配置)
3.被管理的对象交给IoC容器,如何获取到IoC容器?(接口)
4.IoC容器得到后,如何从容器中获取bean?(接口方法)
5.使用Spring导入哪些坐标?(pom.xml)

IoC入门案例步骤:

1.导入Spring坐标(pom.xml)

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

2.定义Spring管理的类(接口)

public interface BookService {
   
    public void save();
}

public interface BookDao {
   
    public void save();
}
public class BookServiceImpl implements BookService {
   

    private BookDao bookDao = new BookDaoImpl();

    public void save() {
   
        System.out.println("book service save ...");
        bookDao.save();
    }
}


public class BookDaoImpl implements BookDao {
   
    public void save() {
   
        System.out.println("book dao save ...");
    }
}

3.创建Spring配置文件,配置对应类作为Spring管理的bean(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-->
    <!--bean标签表示配置bean
    id属性表示给bean起名字
    class属性表示给bean定义类型-->
    <bean id="bookDao" class="com.yan.dao.impl.BookDaoImpl"/>
    <bean id="bookService" class="com.yan.service.impl.BookServiceImpl"/>
</beans>

要注意的是,bean定义时id属性在同一个上下文中不能重复

4.初始化Ioc容器,通过容器获取bean

public class App2 {
   
    public static void main(String[] args) {
   
        //获取IoC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取bean
//        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
//        bookDao.save();

        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}

测试结果:
在这里插入图片描述

DI入门案例思路分析

1.基于IoC管理bean
2.Service中使用new形式创建的Dao对象是否保留?(否)
3.Service中需要的Dao对象如何进入到Service中?(提供方法)
4.Service与Dao间的关系如何描述?(配置)

DI入门案例步骤

1.删除使用new的形式创建对象的代码
2.提供依赖对象对应的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;
    }
}

3.配置service与dao之间的关系

	<bean id="bookService" class="com.yan.service.impl.BookServiceImpl">
        <!--配置service与dao的关系-->
        <!--property标签表示配置当前bean的属性
        name属性表示配置哪一个具体属性
        ref属性表示参照哪一个bean-->
        <property name="bookDao" ref="bookDao"/>
    </bean>

运行结果:(与之前一致)
请添加图片描述


bean配置

bean基础配置

功能:定义Spring核心容器管理的对象
属性列表:

  • id:bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一
  • class:bean的类型,即配置的bean的全路径类名
    格式与范例:
<!--格式-->
<beans>
	<bean/>
    <bean></bean>
</beans>
<!--范例-->
<beans>
	<bean id="bookDao" class="com.yan.dao.impl.BookDaoImpl"/>
    <bean id="bookService" class="com.yan.service.impl.BookServiceImpl"/>
</beans>
bean别名配置

功能:定义bean的别名,可定义多个,可以使用逗号(,)分号(;)空格( )分隔
范例:

	<bean id="bookService" name="service service2,service3;service4" 
	class="com.yan.service.impl.BookServiceImpl">
        <!--配置service与dao的关系-->
        <!--property标签表示配置当前bean的属性
        name属性表示配置哪一个具体属性
        ref属性表示参照哪一个bean-->
        <property name="bookDao" ref="bookDao"/>
    </bean>

获取bean可以通过id或者那么,如果无法获取到,会抛出异常“NoSuchBeanDefinitionException: No bean named ‘service5’ available

bean的作用范围配置

功能:定义bean的作用范围,可选范围如下:

  • singleton:单例(默认)
  • prototype:非单例

范例:

<bean id="bookDao" name="dao" class="com.yan.dao.impl.BookDaoImpl" 
scope="prototype"/>

适合交给容器进行管理的bean

  • 表现层对象
  • 业务层对象
  • 数据层对象
  • 工具对象

不适合交给容器进行管理管理的bean

  • 封装实体的域对象

Bean实例化

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

构造方法(常用)
  • 提供可访问的构造方法
package com.yan.dao.impl;

import com.yan.dao.BookDao;

public class BookDaoImpl implements BookDao {
   
    public BookDaoImpl() {
   
        System.out.println("book dao constructor is running ...");
    }

    public void save() {
   
        System.out.println("book dao save ...");
    }
}
  • 配置
<bean id="bookDao" class="com.yan.dao.impl.BookDaoImpl"/>
  • 无参构造方法如果不存在,将抛出异常BeanCreationException
静态工厂
  • 提供一个静态工厂
public class OrderDaoFactory {
   
    public static OrderDao getOrderDao(){
   
        System.out.println("factory setup ...");
        return new OrderDaoImpl();
    }
}
  • 配置
<bean id="orderDao" class="com.yan.factory.OrderDaoFactory" 
factory-method="getOrderDao"/>
实例工厂与FactoryBean
  • 提供一个实例工厂
public class UserDaoFactory {
   
    public UserDao getUserDao(){
   
        return new UserDaoImpl();
    }
}
  • 配置
    <bean id="userFactory" class="com.yan.factory.UserDaoFactory"/>
    <bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"/>

以下是实例化工厂方式的变种

  • 提供一个FactoryBean
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
   
    //代替原始实例工厂中创建对象的方法
    public UserDao getObject() throws Exception {
   
        return new UserDaoImpl();
    }

    public Class<?> getObjectType() {
   
        return UserDao.class;
    }
}
  • 配置
<bean id="userDao" class="com.yan.factory.UserDaoFactoryBean"/>

Bean生命周期

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

1.提供生命周期控制方法

public class BookDaoImpl implements BookDao {
   

    public void save() {
   
        System.out.println("book dao save ...");
    }
    //表示bean初始化对应的操作
    public void init(){
   
        System.out.println("init ...");
    }
    //表示bean销毁前对应的操作
    public void destroy(){
   
        System.out.println("destroy ...");
    }
}

配置生命周期控制方法

<bean id="bookDao" class="com.yan.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"/>

2.实现InitializingBean, DisposableBean接口

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 ...");
    }

    public void destroy() throws Exception {
   
        System.out.println("service destroy");
    }

    public void afterPropertiesSet() throws Exception {
   
        System.out.println("service init");
    }
}
  • 初始化容器
    • 创建对象(内存分配)
    • 执行构造方法
    • 执行属性注入(set操作)
    • 执行bean初始化方法
  • 使用bean
    • 执行业务操作
  • 关闭/销毁容器
    • 执行bean销毁方法

Bean销毁时机

  • 容器关闭前触发bean的销毁
  • 关闭容器的方式:
    • 手工关闭容器
      ConfigurableApplicationContext 接口 close() 操作
    • 注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机
      ConfigurableApplicationContext 接口 registerShutdownHook() 操作

依赖注入方式

向一个类中传递数据的方式:

  • 普通方法(set方法)
  • 构造方法

依赖注入方式:

  • setter注入
    • 简单类型
    • 引用类型
  • 构造器注入
    • 简单类型
    • 引用类型

setter注入——简单类型
在bean中定义引用类型属性并提供可访问的set方法

public class BookDaoImpl implements BookDao {
   
    private int connectionNum;
    private String databaseName;

    public void setConnectionNum(int connectionNum) {
   
        this.connectionNum = connectionNum;
    }

    public void setDatabaseName(String databaseName) {
   
        this.databaseName = databaseName;
    }

    public void save() {
   
        System.out.println("book dao save ..." + databaseName + "," + connectionNum);
    }
}

配置(value处会自动识别数据类型)

	<bean id="bookDao" class="com.yan.dao.impl.BookDaoImpl">
        <property name="databaseName" value="mysql"/>
        <property name="connectionNum" value="28"/>
    </bean>

测试结果:
在这里插入图片描述
构造器注入——引用类型和简单类型(了解)
在bean中定义引用类型属性并提供可访问的构造方法

public class BookServiceImpl implements BookService {
   
    private BookDao bookDao;
    private UserDao userDao;

    public BookServiceImpl(BookDao bookDao, UserDao userDao) {
   
        this.bookDao = bookDao;
        this.userDao = userDao;
    }

    public void save() {
   
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
}

public class BookDaoImpl implements BookDao {
   
    private int connectionNum;
    private String databaseName;

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

    public void save() {
   
        System.out.println("book dao save ..." + databaseName + "," + connectionNum);
    }
}

配置中使用 constructor-arg 标签 ref 或者 value 属性注入类型对象

<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.yan.dao.impl.BookDaoImpl">
        <constructor-arg name="connectionNum" value="28"/>
        <constructor-arg name="databaseName" value="mysql"/>
    </bean>
    <bean id="userDao" class="com.yan.dao.impl.UserDaoImpl"/>

    <bean id="bookService" class="com.yan.service.impl.BookServiceImpl">
        <constructor-arg name="bookDao" ref="bookDao"/>
        <constructor-arg name="userDao" ref="userDao"/>
    </bean>
</beans>

构造器注入——参数适配(了解)
配置中使用constructor-arg标签type属性设置按形参类型注入

	<!--解决形参名称的问题,与形参名不耦合了-->
    <bean id="bookDao" class="com.yan.dao.impl.BookDaoImpl">
        <constructor-arg type="int" value="28"/>
        <constructor-arg type="java.lang.String" value="mysql"/>
    </bean>
    <bean id="userDao" class="com.yan.dao.impl.UserDaoImpl"/>

    <bean id="bookService" class="com.yan.service.impl.BookServiceImpl">
        <constructor-arg name="bookDao" ref="bookDao"/>
        <constructor-arg name="userDao" ref="userDao"/>
    </bean>

配置中使用constructor-arg标签index属性设置按形参位置注入

	<!-- 解决参数类型重复问题,使用位置解决参数匹配 -->
    <bean id="bookDao" class="com.yan.dao.impl.BookDaoImpl">
        <constructor-arg 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值