SSM学习笔记

SSM框架

第一章 初识Spring

1.1SpringFrameWork 系统架构

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

在这里插入图片描述

1.2核心概念

未使用Spring前

​ 代码书写现状 :代码的耦合度偏高

​ 解决方案:使用对象时,在程序中不要主动使用new产生对象,转换为由外部(Ioc容器)提供对象

使用Spring后

IoC (Inversion of Control)控制反转:对象的创建控制权由程序转移到外部,这种思想称为控制反转。

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

​ 1.Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的外部、

​ 2.IoC容器负责对象的创建、初始化等一系列工作,被创建或者被管理的对象在IoC容器中统称为Bean(在Java中的对象在IoC中被称 为Bean)

DI(Dependency Injection)依赖注入

​ 在容器中建立Bean与Bean之间的依赖关系的过程,称为依赖注入

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r9yJTYkx-1657452083854)(C:\Users\86150\Desktop\笔记\img_SSM\image-20220708180445695.png)]

目标:充分解耦

​ 1.使用IoC容器管理Bean(IoC)

​ 2.在IoC容器内将有依赖关系的Bean进行关系绑定(DI)

最终效果

​ 使用对象时不仅可以直接从IoC容器中获取,并且获取的Bean已经绑定了所有的依赖关系

1.3 IoC的初步使用

​ 1.在pom文件中引入Spring-Context坐标

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

2.在resources文件夹下创建applicationContext的xml文件

​ 其中Bean中id为自行设置的名称,而class对应的是需要被IoC容器管理的类(不能是接口,应为接口不可以被创建对象)

<?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-Context坐标-->

    <bean id="write" class="com.SharkyCake.dao.Impl.writeImpl">

    </bean>

</beans>

3和4.获取IoC容器以及获取所需的Bean

//3.获取IoC容器
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//4.获取Bean
writeImpl write = (writeImpl)ctx.getBean("write");
write.writeSentence();

1.4 DI入门案例

​ 思路:

​ 1.基于IoC管理Bean

​ 2.Service中使用new形式创建的Dao对象是否保留(否)

​ 3.Service中需要的Dao对象如何进入到Service中?(提供方发)

​ 4.Service与Dao之间的关系如何描述?(配置)

5.将业务层中new出来dao的代码删除

6.创建对应的setter方法

package com.SharkyCake.service.Impl;

import com.SharkyCake.dao.Impl.writeImpl;
import com.SharkyCake.service.writeService;

public class writeServiceImpl implements writeService {
    //5.删除业务层中使用new的方式创建的dao对象
    private writeImpl writeDao /*= new writeImpl()*/;

    @Override
    public void writeServiceSentence() {
        writeDao.writeSentence();
        System.out.println("Write Service Sentence......");
    }
    //6.提供对应的set方法
    public void setWriteDao(writeImpl writeDao){
      this.writeDao = writeDao;
    };
}

7.在applicationContext中修改对应属性

 <!--7.配置service与dao之间的关系 -->
    <!--property表示配置当前Bean的属性-->
    <!--name表示配置哪一个具体的属性(此处的属性值为对应writeService Bean中的属性值)
        ref属性表示name参照的是哪一个Bean-->
<bean id = "writeService" class="com.SharkyCake.service.Impl.writeServiceImpl">
    <property name="writeDao" ref="write"/>
</bean>

第二章 Bean

2.1 Bean的别名

类别描述
名称name
类型属性
所属bean标签
功能定义Bean 的别名,可以定义多个,使用逗号(,)分号(;)空格( )分割
范例
注意事项

获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常	
NoSuchBeanDefinitionExceptionNoSuchBeanDefinitionException: No bean named 'bookServiceImpl' available

2.2 Bean的作用范围

类型描述
名称scope
类型属性
所属bean标签
功能定义bean的作用范围,可选范围如下 singleton:单例(默认)prototype:非单例
范例

为什么bean默认设置为单例?

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

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

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

  • 封装实体的域对象

2.2Bean的实例化

实例化Bean的三种方式——构造方法(常用)

​ 即在Bean对应的类中创建可访问的(public和private都可以使用)无参构造方法(或者不写类会自动创建无参构造)

​ 人如果无参构造方法不存在,将会抛出异常BeanCreationException

实例化Bean的三种方式——静态工厂(了解)

​ 首先在factory包下创建对应的factory工厂类

import com.SharkyCake.dao.Impl.writeImpl;

public class writeDaoFactory {
    //创建工厂对象
    public static writeImpl getWriteDao(){
        return new writeImpl();
    }
}

​ 在Bean中创建所需的Dao对象 与普通方法不同的是

​ class属性要改为对应使用的工厂类

​ factory-method:对应所需的创建实体类的方法

<bean id="writeDao" class="com.SharkyCake.factory.writeDaoFactory" factory-method="getWriteDao"/>
实例化Bean的三种方式——实例工厂(了解)

​ 实例工厂与静态工厂不同的地方就在于,静态工厂他对应的工厂对象不需要创建对象即可获取对应Dao对象,但是实例工厂就需要创建 实例的工厂对象来获取对应的Dao对象,以至于需要创建Factory的Bean对象(冗余)

import com.SharkyCake.dao.Impl.writeImpl;

public class writeFactory {
    public writeImpl getwriteImpl(){

        return new writeImpl();
    }
}
<!--3.通过实例工厂创建bean-->
<!--1先创建对应的实例工厂对象-->
<bean id="writeDaoFactory" class="com.SharkyCake.factory.writeFactory"/>
<!--通过实例工厂对象来获取对应的Dao-->
<bean id="writeDao" factory-method="getwriteImpl" factory-bean="writeDaoFactory"/>
实例化Bean的第四种方式——FactoryBean(重点)

此时创建工厂对象要实现FactoryBean这个接口,而且这个接口还是个泛型,需要填写所需返回的Dao对象

import com.SharkyCake.dao.Impl.writeImpl;
import com.SharkyCake.dao.write;
import org.springframework.beans.factory.FactoryBean;

public class writeFactoryBean implements FactoryBean<writeImpl> {
    /**
     * 返回所需的Dao对象
     * @return
     * @throws Exception
     */
    @Override
    public writeImpl getObject() throws Exception {
        return new writeImpl();
    }

    /**
     * 返回对应的类字节码
     * @return
     */
    @Override
    public Class<?> getObjectType() {
        return writeImpl.class;
    }

    /**
     * 设置bean 是否为单例模式 默认为单例模式
     * @return
     */
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}

<!--方法四:通过FactoryBean创建对象-->
<bean id="writeImpl" class="com.SharkyCake.factory.writeFactoryBean"/>

2.3 bean的生命周期

bean的创建以及销毁

第一种方式,在对应class中创建Init和Destory方法海表Bean的创建以及销毁时要进行的操作

package com.sharkyCake.service.Impl;

import com.sharkyCake.service.bookService;

public class bookServiceImpl implements bookService {
    public void init(){
        System.out.println("init.....");
    }

    public void readBook(){
        System.out.println("Read.....");
    }

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

并且在配置文件中使用 init_method 和 destroy-method 来绑定对应的init和destroy方法

<bean id="Book" class="com.sharkyCake.service.Impl.bookServiceImpl" init-method="init" destroy-method="destroy"/>

要注意:destroy方法不会自动执行,在JVM虚拟机退出时不会销毁bean,

​ 执行bean的销毁操作需要IoC容器关闭时才会进行销毁(此方法暴力关闭)

​ 或者注册一个钩子函数,不论在哪一出代码都可以执行

import com.sharkyCake.service.Impl.bookServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class springTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        bookServiceImpl book = (bookServiceImpl)context.getBean("Book");
        book.readBook();
        //context.close();
        context.registerShutdownHook();
    }
}

第二种方法(了解)在对应得class中继承InitializingBean, DisposableBean两种接口并实现对应的方法,即可不用再配置文件中绑定

init-method 和 destroy-method方法

bean的销毁时机

​ 容器关闭前触发bean的销毁

​ 关闭容器方式:

​ 1.手工关闭容器 ConfigurationApllicationContext接口close()操作

​ 2.注册关闭钩子,在虚拟机退出前先关闭容器再推出虚拟机

​ ConfigurationApplicationContext接口registerShutDownHook() 操作

第三章 依赖注入

2.1 setter注入

2.1.1普通数据类型注入

​ setter注入的意思就是再class中有对应得属性值的set方法,并且在配置文件中创建对应的属性来对bean中的值进行控制:

​ 例子如下所示:

public class bookDaoImpl {
    private int bookNum;
    private String BookName;

    public void readByDao (){
        System.out.println("readByDao....."+bookNum+BookName);
    }

    public void setBookNum(int bookNum) {
        this.bookNum = bookNum;
    }

    public void setBookName(String bookName) {
        BookName = bookName;
    }
}
<bean id="BookDao" class="com.sharkyCake.dao.Impl.bookDaoImpl">
    value属性的意思为set前面的某一个普通数据类型所设的值
    <property name="bookName" value="数据结构与算法"/>
    <property name="bookNum" value="100"/>
</bean>
2.1.2引用类型注入

​ 在一个类中如果引用了其他类,并且创建了对象,则要在Bean中同样加入property属性并且在property中的ref写出所引用的类的Bean创建时的Name值

要注意这里的ref指代的是private bookDaoImpl bookDao;中的bookDao而不是set方法中的形参

​ 例如:

import com.sharkyCake.dao.Impl.bookDaoImpl;
import com.sharkyCake.dao.bookDao;
import com.sharkyCake.service.bookService;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class bookServiceImpl implements bookService, InitializingBean, DisposableBean {
    private bookDaoImpl bookDao;

    public void setBookDao(bookDaoImpl bookDao) {
        this.bookDao = bookDao;
    }
    public void init(){
        System.out.println("init.....");
    }

    public void readBook(){
        bookDao.readByDao();
        System.out.println("Read.....");
    }

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

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Init through InitializingBean");
    }

    /*@Override
    public void destroy() throws Exception {

    }*/
<bean id="BookDao" class="com.sharkyCake.dao.Impl.bookDaoImpl">
    <property name="bookName" value="数据结构与算法"/>
    <property name="bookNum" value="100"/>
</bean>




<bean id="Book" class="com.sharkyCake.service.Impl.bookServiceImpl" init-method="init" destroy-method="destroy">
    在这里要注意 尽管在上面的实现类中可以将BookDaoImpl创建为接口类型的,但是在这里的ref就会报错
    要求bookDao的对象类型和后面ref的对象类型一致
    <property name="bookDao" ref="BookDao"/>
</bean>

2.2 构造器注入

​ 构造器注入与setter注入基本相同,需要改变的地方就是将class中的set方法修改变成构建对象的方法,并且在配置文件中修改property为constructor-arg 此时的name指的是java文件中constructor方法的形式参数的名称。

<bean id="BookDao" class="com.sharkyCake.dao.Impl.bookDaoImpl">
    <constructor-arg name="bookName" value="fuk"/>
    <constructor-arg name="bookNum" value="1"/>
</bean>
public class bookDaoImpl {
    private int bookNum;
    private String BookName;
	
	public bookDaoImpl(int bookNum, String bookName) {
        this.bookNum = bookNum;
        BookName = bookName;
    }
    
    public void readByDao (){
        System.out.println("readByDao....."+bookNum+BookName);
    }

    public void setBookNum(int bookNum) {
        this.bookNum = bookNum;
    }

    public void setBookName(String bookName) {
        BookName = bookName;
    }
}

但是这种方法属于紧耦合,形参名字改变导致bean中字段也要改变

2.3 依赖注入方式的选择

​ 1.强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现

​ 2.可选以来使用setter注入进行,灵活性强

​ 3.Spring框架倡导使用构造器,第三方框架大多数采用构造器注入的形式进行数据初始化,相对严谨

​ 4.如果有必要可以两者同时使用,使用构造器完成强制依赖的注入,使用setter注入完成可选依赖的注入

​ 5.实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入

6.自己开发的模块建议使用setter注入

2.4 依赖自动装配

​ 如何使用自动装配

​ 配置使用bean标签autowire属性设置自动装配的类型

<bean id="BookDao" class="com.sharkyCake.dao.Impl.bookDaoImpl" auto-wire="byType">
    <constructor-arg name="bookName" value="fuk"/>
    <constructor-arg name="bookNum" value="1"/>
    <property name="bookName" value="数据结构与算法"/>
    <property name="bookNum" value="100"/>
</bean>

依赖自动装配的特征(也需要提供set方法)

  • 自动装配用于引用类型依赖注入,不能对简单类型进行进行操作。
  • 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一(即会按照bean中引用的对象类型来寻找对应的bean),推荐使用
  • 试图用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
  • 自动装配优先级低于setter与构造器注入,同时出现是自动装配配置失效

2.5 集合注入

集合注入的几种形式array,list,map,properties

首先定义这几个集合类型

private int[] a;
    private List<String> list;
    private Map<String,String> map;
    private Properties properties;

    public void setA(int[] a) {
        this.a = a;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

其次在配置文件中进行配置

<property name="a">
    <array>
        <value>1</value>
        <value>2</value>
        <value>3</value>
    </array>
</property>
<property name="list">
    <list>
        <value>w</value>
        <value>e</value>
        <value>e</value>
    </list>
</property>

<property name="map">
    <map>
        <entry key="1" value="2"/>
        <entry key="1" value="2"/>
        <entry key="1" value="2"/>
    </map>
</property>

<property name="properties">
    <props>
        <prop key="1">2</prop>
        <prop key="1">2</prop>
        <prop key="1">2</prop>
    </props>
</property>

2.6 加载properties配置信息

如何加载properties文件的信息

首先要修改appliactionContext文件的头信息,创建出一个Context域来存放读取的数据

xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd"

其次读取文件即可,读取出来的文件使用${}通配符获取数据

<context:property-placeholder location="jdbc.properties"/>
<!--不加载系统属性-->
<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
<!--加载多个properties文件-->
<context:property-placeholder location="jdbc.properties,applicationContext.xml"/>
<!--加载所有properties文件-->
<context:property-placeholder location="*.properties"/>
<!--加载properties文件标准格式-->
<context:property-placeholder location="classpath:*.properties"/>
<!--从类路径或者jar包中搜索并加载properties文件-->
<context:property-placeholder location="classpath*:*.properties"/>

<bean name="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

2.7 容器

容器相关
  • BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象是,加载的bean延迟加载
  • ApplicationContext接口时Spring容器的核心接口,初始化bean时立即加载
  • ApplicationContext接口提供基础的bean操作相关方法,通过其他接口拓展其功能
  • ApplicationContext接口常用初始化类
    • ClassPathXmlApplicationContext
    • FilesystemXmlApplicationContext
bean相关

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oy2YRmDc-1657452083855)(C:\Users\86150\Desktop\笔记\img_SSM\image-20220710174021346.png)]

依赖注入相关

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c396D2Z0-1657452083856)(C:\Users\86150\Desktop\笔记\img_SSM\image-20220710174418232.png)]

第四章 注解开发

4.1 注解开发bean

​ 在使用注解开发bean时,将注解直接写在对应的类文件的头部

使用**@Component()**注解,括号内可以写String类型的名字,写的名字对应就是在applicationContext中的id

括号中不写内容也可,但在getBean是就要使用Class名来获取对应的Bean

例子:

1.首先要修改Spring的头文件(创建Context域)

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

2.在要创建Bean的类中使用注解开发

3.在核心配置文件中通过组件扫描加载bean

@Component("BookDao")
public class Impl implements bookService {

    public void bookRead(){
        System.out.println("readBook......");
    }
}
扫描包
<context:component-scan base-package="com.sharkyCake" />
  • Spring还提供@Component注解的三个衍生注解
    • @Controller:用于表现层bean定义
    • @Service:用于业务层bean定义
    • @Repository :用于数据层bean定义

4.2 纯注解开发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

戚风蛋糕`

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

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

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

打赏作者

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

抵扣说明:

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

余额充值