【Spring】Sring基础概念(黑马SSM学习笔记)

Spring简介

Spring是什么

Spring是分层的Java SE/EE应用的full-stack轻量级开源框架,以Ioc(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核

提供了展现层SpringMVC和持久层Spring JDBCTemplate以及业务层事务管理等众多的应用技术,还能整合开源世界众多注明的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开发框架

Spring发展

……

Spring优势

  1. 方便解耦,简化开发

    通过Spring提供的Ioc容器,可以将对象间的依赖关系交由Spring控制,避免硬编码造成的过渡耦合。

    用户不必为单例模式类,属性文件解析等底层需求编写代码,可以更加专注于上层的应用

  2. AOP编程支持

    通过Spring的AOP功能,方便面向切面编程,许多不容易用传统OOP实现的功能可以通过AOP实现

  3. 声明式事务的支持

    通过声明式方式灵活的进行事务管理,提高开发效率和质量。将开发者从单调烦闷的事务管理代码中解脱出来

  4. 方便程序测试

    可以使用非容器依赖的编程方式进行几乎所有的测试工作。

  5. 方便集成各种优秀框架

    Struts、Hibernate、Hessian、Quartz

  6. 降低Java EE API 的使用难度

    Spring对Java EE API(例如JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使用这些API使用难度大大减低

  7. Java源码经典学习典范

    Spring源代码设计巧妙,结构清晰,匠心独用……

Spring体系结构

image.png

Core Container :核心容器

Spring快速入门

Spring程序开发步骤

不用Spring的一般步骤

cc.mllt.service.UserServicelmpI

UserDao userDao = new UserDaoImpI(

cc.mllt.dao.UserDaoImpI

save方法
update方法
……

xml配置文件

id标识 = cc.mllt.dao.UserDaoImpI

使用Spring框架

cc.mllt.service.UserServicelmpI

UserDao userDao = Spring客户端.getBean(id标识)

cc.mllt.dao.UserDaoImpI

save方法
update方法
……

xml配置文件

id标识 = cc.mllt.dao.UserDaoImpI

Spring框架

读取xml文件
根据id标识获取bean全限定名
通过反射创建Bean对象
返回对象

图示

7X@JPFSZ2BPR9H_X3YC.jpg

总结

  • 导入Spring开发的基本包坐标
  • 编写Dao接口和实现类
  • 创建Spring核心配置文件
  • 在Spring配置文件中配置UserDaoImpI
  • 使用Spring的API获得Bean实例

实战

项目文件:黑马程序员SSM框架教程\edu01\Demo1

创建项目

image.png

添加Spring框架

在pom.xml文件中添加以下内容

    <!--Spring Framework-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>

image.png

编写接口方法

在创建出来的UserDao中简单的写一个方法

public interface UserDao {
    public void save();
}

image.png

实例化接口

image.png

image.png

创建完成目录结构如下

image.png

在新建的这个UserDaoImpl文件中写入以下内容

public class UserDaoImpl implements UserDao {
    public void save(){
        System.out.println("[萌狼蓝天]save running....");
    }
}

image.png

创建配置文件

image.png

image.png

image.png

image.png

配置完成

编写测试代码

image.png

写入如下代码

package cc.mllt.dao.demo;

import cc.mllt.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserDaoDemo {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取xml文件
        UserDao userDao = (UserDao) app.getBean("userDao");
        // ① app.getBean("userDao")里面写的是刚才xml文件里面配置的bean的id名称
        // ② 将Objec类型强制转换为UserDao类型
        userDao.save();
    }
}

image.png

知识小结

Spring开发步骤

  1. 导入坐标
  2. 创建bean
  3. 创建applicationContext.xml(这个名称可以自定义)
  4. 在配置文件中进行配置
  5. 创建ApplicationContext对象getBean

Spring配置文件

bean标签基本配置

image.png

用于配置对象交由Spring创建,默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能成功创建

基本属性

  • id:Bean实例在Spring容器中的唯一标识
  • class:Bean的全限定名称

bean标签范围配置

scope:指的是对象的作用范围,取值如下:

取值范围 说明
singleton 默认值,单例的。(单对象)
prototype 多例的。(多对象)
request WEB项目中,Spring创建一个Bean对象,将对象放入到request域中
session WEB项目中,Spring创建一个Bean对象,将对象放入到session域中
global session WEB项目中,应用在Portlet环境,如果没有Portlet环境那么globalSession相当于session

测试scope

本测试基于项目 黑马程序员SSM框架教程\edu01\Demo1

<bean id="userDao" class="cc.mllt.dao.impl.UserDaoImpl" scope="singleton"/>

image.png

添加单元测试包

在pom.xml中添加如下代码

<!--junit-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
    </dependency>

image.png

测试scope

image.png

 @Test
    //测试scope属性
    public  void test1(){
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao1 = (UserDao) app.getBean("userDao");
        UserDao userDao2 = (UserDao) app.getBean("userDao");
        System.out.println(userDao1);
        System.out.println(userDao2);
    }

image.png

image.png

image.png

观察结果发现,是一样的,说明在容器中只存在一个

回到applicationContext.xml中,更改scope属性值

<bean id="userDao" class="cc.mllt.dao.impl.UserDaoImpl" scope="prototype"/>

image.png

继续测试

image.png

image.png

观察结果发现,输出的结果不一致(地址不一样)。

说明容器中存在的UserDao不止一个

测试bean的创建时机、

测试

回到applicationContext.xml中,更改scope属性值

<bean id="userDao" class="cc.mllt.dao.impl.UserDaoImpl" scope="singleton"/>

image.png

image.png

image.png

image.png

image.png

回到applicationContext.xml中,更改scope属性值

<bean id="userDao" class="cc.mllt.dao.impl.UserDaoImpl" scope="prototype"/>

再进行测试

image.png

总结
1)当scope的取值为singleton时

Bean的实例化个数: 1个
Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例
Bean的生命周期:
●对象创建: 当应用加载,创建容器时,对象就被创建了
●对象运行: 只要容器在,对象一直活着
●对象销毁: 当应用卸载,销毁容器时,对象就被销毁了

2)当scope的取值为prototype时

Bean的实例化个数:多个
Bean的实例化时机:当调用getBean0方法时实例化Bean
●对象创建: 当使用对象时,创建新的对象实例
●对象运行: 只要对象在使用中,就一-直活着
●对象销毁: 当对象长时间不用时,被Java的垃圾回收器回收了

Bean的生命周期

init-method:指定类中的初始化方法名称

destroy-method:指定类中销毁方法的名称

image.png

    public void ml_init(){
        System.out.println("[萌狼蓝天]]UserDaoImpl-初始化方法");
    }
    public void ml_destroy(){
        System.out.println("[萌狼蓝天]UserDaoImpl-销毁方法");
    }

目前这两个方法没有被使用

为了能让这两个方法被使用,现在去修改配置文件applicationContext.xml

    <bean id="userDao" class="cc.mllt.dao.impl.UserDaoImpl" scope="prototype" init-method="ml_init" destroy-method="ml_destroy"/>

回到测试代码

image.png

<?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="userDao" class="cc.mllt.dao.impl.UserDaoImpl" scope="singleton" init-method="ml_init" destroy-method="ml_destroy"/>
</beans>

image.png

为什么没有销毁?

因为这是一个单元测试,并没有在Tomcat服务器内部

单元测试一执行完毕就会销毁,没有来得及执行销毁方法中的打印内容

那怎么样测试呢?将容器设置为手动关闭!

bean实例化的三种方式

  • 无参构造方法实例化
  • 工厂静态方法实例化
  • 工厂实例方法实例化

工厂静态方法化

image.png

package cc.mllt.dao.factory;

import cc.mllt.dao.UserDao;
import cc.mllt.dao.impl.UserDaoImpl;

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

发现包放的有问题,更改一下路径

image.png

image.png

image.png

image.png

更改配置文件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="userDao" class="cc.mllt.dao.impl.UserDaoImpl" scope="singleton" init-method="ml_init" destroy-method="ml_destroy"/>-->
<!--    静态工厂构造-->
    <bean id="userDao" class="cc.mllt.factory.StaticFactory" factory-method="getUserDao" />
</beans>

image.png

工厂实例方法实例化

image.png

package cc.mllt.factory;

import cc.mllt.dao.UserDao;
import cc.mllt.dao.impl.UserDaoImpl;

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

配置文件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="userDao" class="cc.mllt.dao.impl.UserDaoImpl" scope="singleton" init-method="ml_init" destroy-method="ml_destroy"/>-->
<!--    静态工厂构造-->
<!--    <bean id="userDao" class="cc.mllt.factory.StaticFactory" factory-method="getUserDao" />-->
<!--    工厂实例实例化(动态工厂)-->
    <bean id="factory" class="cc.mllt.factory.DynamicFactory"></bean>
    <bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
</beans>

测试

image.png

Spring配置文件

Bean的依赖注入分析

image.png

image.png

image.png

package cc.mllt.service.ipml;

import cc.mllt.dao.UserDao;
import cc.mllt.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceImpl implements UserService {
    @Override
    public void save() {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) app.getBean("userDao");
        userDao.save();
    }
}

image.png

image.png

package cc.mllt.demo;

import cc.mllt.service.UserService;
import cc.mllt.service.ipml.UserServiceImpl;

public class UserController {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        userService.save();
    }
}

image.png

现在

image.png

这是由于还没有去修改配置未见ApplicationContext.xml

image.png

image.png

UserDao此时在UserService内部

Bean依赖注入概念

依赖注入(Dependency Injection):Spring框架核心IOC的具体实现

IOC解耦只是降低了他们的依赖关系,但不会消除。例如:业务层仍然会调用持久层的方法

Bean的依赖注入方式

set方法

image.png

image.png

image.png

image.png

image.png

p命名空间注入的本质也是set方法注入,但是比起上述的set方法注入更加方便,主要体现在配置文件中

(1)引入p命名空间:

xmlns:p="http://www.springframework.org/schema/p"

(2)修改注入方法

 <bean id="userService" class="cc.mllt.service.ipml.UserServiceImpl" p:userDao-ref="userDao"></bean>

image.png

image.png

构造方法

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    无参构造-->
<!--    <bean id="userDao" class="cc.mllt.dao.impl.UserDaoImpl" scope="singleton" init-method="ml_init" destroy-method="ml_destroy"/>-->
<!--    静态工厂构造-->
<!--    <bean id="userDao" class="cc.mllt.factory.StaticFactory" factory-method="getUserDao" />-->
<!--    工厂实例实例化(动态工厂)-->
<!--    <bean id="factory" class="cc.mllt.factory.DynamicFactory"></bean>-->
<!--    <bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>-->
<!--    service-->

<!--    set构造方法-->
<!--    <bean id="userDao" class="cc.mllt.dao.impl.UserDaoImpl"></bean>-->
<!--    <bean id="userService" class="cc.mllt.service.ipml.UserServiceImpl">-->
<!--        <property name="userDao" ref="userDao"></property>-->
<!--    </bean>-->
<!--        <bean id="userService" class="cc.mllt.service.ipml.UserServiceImpl" p:userDao-ref="userDao"></bean>-->
<!--构造方法-->
    <bean id="userDao" class="cc.mllt.dao.impl.UserDaoImpl"></bean>
        <bean id="userService" class="cc.mllt.service.ipml.UserServiceImpl">
           <constructor-arg name="userDao" ref="userDao"></constructor-arg>
        </bean>
</beans>

image.png

package cc.mllt.service.ipml;

import cc.mllt.dao.UserDao;
import cc.mllt.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public UserServiceImpl(UserDao userDao){
        this.userDao = userDao;
    }
    public UserServiceImpl(){

    }
//    private UserDao userDao;
//    public void  setUserDao(UserDao userDao){
//        this.userDao = userDao;
//    }
    @Override
    public void save() {
//        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//        UserDao userDao = (UserDao) app.getBean("userDao");
        userDao.save();
    }
}

image.png

运行

image.png

Bean的依赖注入的数据类型

上面的操作,都是注入Bean,除了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入

注入数据的三种数据类型

  • 普通数据类型
  • 引用数据类型
  • 集合数据类型

普通数据类型

引用数据类型

image.png

image.png

测试

image.png

集合数据类型

image.png

创建User

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

测试

image.png

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <bean id="userService" class="cc.mllt.service.ipml.UserServiceImpl">
           <constructor-arg name="userDao" ref="userDao"></constructor-arg>
        </bean>
        <bean id="userDao" class="cc.mllt.dao.impl.UserDaoImpl">
            <property name="strList">
                <list>
                    <value>123</value>
                    <value>456</value>
                    <value>789</value>
                </list>
            </property>
            <property name="userMap">
                <map>
                    <entry key="u1" value-ref="user1"></entry>
                    <entry key="u2" value-ref="user2"></entry>
                </map>
            </property>
        </bean>
    <bean id="user1" class="cc.mllt.domain.User">
        <property name="name" value="唐"/>
        <property name="addr" value="背景"/>
    </bean>
    <bean id="user2" class="cc.mllt.domain.User">
        <property name="name" value="下键"/>
        <property name="addr" value="上弹"/>
    </bean>
</beans>

image.png

image.png

image.png

image.png

image.png

image.png

测试

image.png

引入其他配置文件(分模块开发)

实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积庞大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件中通过import标签进行加载

import resource="applicationContext-xxx.xml"/>

例如,创建一个用户模块和一个商品模块

image.png

image.png

知识点小结

<bean>标签
	id属性:在容器中Bean实例的唯一标识,不允许重复
	class属性:要实例化的Bean的全限定名
	scope属性:Bean作用范围,常用是Singleton(默认)和proto
	<property>标签:属性注入
		name属性:属性名称
		value属性:注入的普通的属性值
		ref属性:注入对象引用值
		<list>标签
		<map>标签
		<properties>标签
	<constructor-arg>标签
<import>标签:导入其他的Spring的分文件

Spring相关API

ApplicationContext的继承体系

applicationContext:接口类型,代表应用上下文,可以通过它的实例获得Spring容器中的Bean对象

ApplicationContext的实现类

(1)ClassPathXmlApplicationContext

从类的根路径下加载配置文件,推荐使用

image.png

(2)FileSystemXmlApplicationContext

从磁盘路径加载文件,配置文件可以在磁盘的任意位置

image.png

image.png

(3)AnnotationConfigApplication

当使用注解配置容器对象时,需要使用此类来创建Spring容器,他用来读取注解

getBean()方法的使用

方法1:根据Id的方式

允许容器中出现多个相同类型的bean

image.png

方法2:

image.png

知识要点

Spring重点API

ApplicationContext app = new ClassPathXmlApplicationContext('x0ml文件名');
app.getBean('id');
app.getBean(class)

关于本笔记的配套视频

https://www.bilibili.com/video/BV1WZ4y1P7Bp/

萌狼蓝天只看到了P20,所以笔记之写到了P20。后面的你们自己慢慢看,自己写笔记吧!

posted @ 2022-09-23 16:07  萌狼蓝天  阅读(188)  评论(0编辑  收藏  举报