草庐IT

Spring Framework 基础入门

从零开始的JAVA世界 2023-08-11 原文

参考资料

spring官网 https://spring.io/

https://www.bilibili.com/video/BV1Fi4y1S7ix?p=4&vd_source=c581024b8cd9585ec6a75c56ac05571a

1. 初识Spring

Spring是一个开源的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。

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



Spring Framework 项目 是Spring生态的核心。
Spring Boot 项目 让开发更简单、更快速。
Spring Cloud 项目 分布式项目。

2. Spring Framework 系统架构

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

架构图

3. Spring Framework 学习

1. 核心思想

Ioc控制翻转

使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权有程序转移到外部,此思想称为控制翻转。

Spring技术对Ioc思想进行了实现

Spring提供了一个容器,称为Ioc容器,用来充当Ioc思想中的外部。

Ioc容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在Ioc容器中统称为Bean。

DI 依赖注入

在容器中给依赖的属性赋值的过程,称为依赖注入。

Spring 使用Ioc容器管理Bean(IoC),并在创建Bean时将有依赖关系的进行关系绑定(DI),向外提供完整的对象。同时大大降低了对象间的耦合。

2. IoC 快速入门案例

  1. 引入依赖
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.20</version>
        </dependency>
  1. 创建类
package com.xin.service.impl;

public class UserServiceImpl {

    private String name ;
    
    public void save(){
        System.out.println("userService:save()");
    }

    public void setName(String name) {
        this.name = name;
    }
}
  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">
    //添加Bean
    <bean id="userService" class="com.xin.service.impl.UserServiceImpl"></bean>
    
</beans>
  1. 测试
package com.xin.service;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

    @Test
    public void testSave(){
        //创建容器,加载配置文件。
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //根据Bean id 获取对应的Bean对象。
        UserService userService = context.getBean("userService", UserService.class);
        //调用UserService对象中的方法
        userService.save();
    }
}

3. IoC 底层原理

xml解析+工厂设计模式+反射

  1. 原始方式 new



对象间强耦合在一起。

  1. 使用工厂模式降低耦合度


3. Spring 将对象的定义信息提到配置文件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="userService" class="com.xin.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>  <!--DI依赖注入,配置userService和userDao两个对象间的关系-->
    </bean>

    <bean id="userDao" class="com.xin.dao.UserDao"/>

</beans>
public class UserServiceTest {

    @Test
    public void testSave(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.save();
    }
}

4. DI 依赖注入

两种方式:

  1. setter注入
<?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="userService" class="com.xin.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>  <!--setter注入,需要该属性有set方法-->
    </bean>

    <bean id="userDao" class="com.xin.dao.UserDao"/>

</beans>
  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">

    <bean id="userService" class="com.xin.service.impl.UserServiceImpl">
        <constructor-arg name="userDao" ref="userDao"/>
    </bean>

    <bean id="userDao" class="com.xin.dao.UserDao"/>

</beans>

5. Bean的别名 name

    <bean id="userService" name="service service2" class="com.xin.service.impl.UserServiceImpl"></bean>

6. Bean的作用域 scope

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

    <!--方式一 构造器实例化Bean (默认使用空参构造)-->
    <bean id="userService" class="com.xin.service.impl.UserServiceImpl"/>

    <!--方式二 静态工厂创建对象-->
    <bean id="userService2" class="com.xin.service.impl.ObjectFactory" factory-method="getObject"/>

    <!--方式三 实例工厂创建对象-->
    <bean id="instanceObjectFactory" class="com.xin.service.impl.InstanceObjectFactory"/>
    <bean id="userService3" factory-bean="instanceObjectFactory" factory-method="getObject"/>

    <!--方式四 实现BeanFactory接口,规范实例化工厂-->
    <bean id="userService4" class="com.xin.service.impl.UserServiceObjectFactory"/>

</beans>
package com.xin.service.impl;

public class UserServiceImpl {

    public UserServiceImpl() {
        System.out.println("空参构造");
    }
}

//静态工厂
class ObjectFactory {
    
    public static UserServiceImpl getObject() {
        return new UserServiceImpl();
    }
}

//实例工厂
class InstanceObjectFactory {

    public UserServiceImpl getObject() {
        return new UserServiceImpl();
    }
}
//Spring 提供了BeanFactory接口来规范实例化工厂
public class UserServiceObjectFactory implements FactoryBean<UserService> {

    @Override
    public UserService getObject() throws Exception {
        return new UserServiceImpl();//返回实例化对象
    }

    @Override
    public Class<?> getObjectType() { 
        return UserService.class;//类型
    }

    @Override
    public boolean isSingleton() {
        return true;//是否是单例
    }
}

8. Bean的生命周期

  1. 实例化 (分配内存、执行构造方法() )
  2. 属性注入
  3. 执行初始化 (配置文件init-method 或 实现接口InitializingBean)
  4. 使用Bean对象,执行业务操作。
  5. 执行销毁方法 (配置文件 destroy-method 或实现接口DisposableBean)
<?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="userService" init-method="init" destroy-method="dest" class="com.xin.service.impl.UserServiceImpl"/>
	
</beans>

关闭容器的方式

public class UserServiceTest {

    @Test
    public void testSave() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        //方式一 //注册关闭钩子,JVM虚拟机关闭前时才先关闭容器。
        context.registerShutdownHook();
        
        //方式二 //直接关闭容器。
        context.close();
    }
}

9. 自动装配

IoC容器根据Bean所依赖的资源在容器中自动查找并注入到Bean中的过程称为自动装配。不用setter注入和构造器注入了。


10. 配置DataSource

        <!--Druid数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url"
                  value=" jdbc:mysql://localhost:3306/xin?serverTimezone=UTC&amp;characterEncoding=utf8&amp;useUnicode=true&amp;useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

11. 加载Properties配置文件

    <!--classpath*: 其他jar包配置文件    -->
    <context:property-placeholder location="db.properties" system-properties-mode="NEVER"/>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driverClassName}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
    </bean>
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/xin?serverTimezone=UTC&useSSL=false
username=root
password=123456

12. 容器、Bean、依赖注入总结

@Test
public void testSave() {
    //方式一: 类路径加载配置文件
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    //加载多个配置文件
    context = new ClassPathXmlApplicationContext("applicationContext.xml,applicationContext2.xml");

    //方式二:文件路径加载配置文件
    context = new FileSystemXmlApplicationContext("D:\\Project\\spring\\src\\main\\resources\\applicationContext.xml");
}



13. 注解配置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"
       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
       https://www.springframework.org/schema/context/spring-context.xsd">

    <!--配合扫描的根路径,会扫描该包下及其子包中的所有带有@Component注解的类,注入到容器中。-->
    <context:component-scan base-package="com.xin"/>

</beans>

要放到容器的类上加@Component注解

package com.xin.service.impl;

import org.springframework.stereotype.Component;

@Component
public class UserServiceImpl {
}

4. 纯注解开发

1. 配置类

package com.xin.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration //配置类
@ComponentScan("com.xin") //配置包扫描路径
public class SpringConfig {
}
public class SpringAnnotationTest {

    public void testSpringAnnotation() {
        //传入配置类,创建容器.
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    }
}

2. Bean的作用域和生命周期

@Service
@Scope("singleton")
public class UserService {

    @PostConstruct
    public void init() {
    }

    @PreDestroy
    public void destroy() {
    }
}

3. 依赖注入

@Service("userService")
@Scope("singleton")
public class UserServiceImpl implements UserService {

    @Autowired //暴力反射,不需要提供setter方法
    @Qualifier("userDao") //多个类型时,指定名称
    private UserDao userDao;

    @Value("zhx") //简单类型
    private String name;

    @Override
    public void save(){
        System.out.println(userDao);
        System.out.println(name);
        userDao.save();
    }
}

4. 注入第三方Bean

@Configuration //配置类
@ComponentScan("com.xin") //配置包扫描路径
@PropertySource("classpath:db.properties") //加载Properties文件
@Import(JDBCConfig.class) //推荐使用,也可以直接在JDBCConfig上加@Configuration但那样混乱,不能只管的知道导了那些配置。
public class SpringConfig {
}
public class JDBCConfig {

    @Value("${driverClassName}")
    private String driverClassName;
    @Value("${url}")
    private String url;
    @Value("${username}")
    private String username;
    @Value("${password}")
    private String password;

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

5. @Value(“${}”) 会读取系统变量,重名会覆盖

@Value("${username}")
private String username; //系统变量会覆盖配置文件中的,因此平常自定义属性时避免与系统环境变量重名,最好加上前缀。
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/xin?serverTimezone=UTC&useSSL=false
jdbc.username=root
jdbc.password=123456

6. 第三方Bean需要依赖其他Bean

public class JDBCConfig {

    @Value("${driverClassName}")
    private String driverClassName;
    @Value("${url}")
    private String url;
    @Value("${username}")
    private String username;
    @Value("${password}")
    private String password;

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource){ //形参会自动装配
        return new JdbcTemplate(dataSource);
    }
}

7. 注解开发总结

有关Spring Framework 基础入门的更多相关文章

  1. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  2. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  3. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  4. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  5. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  6. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  7. 【网络】-- 网络基础 - 2

    (本文是网络的宏观的概念铺垫)目录计算机网络背景网络发展认识"协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型报头以太网碰撞路由器IP地址和MAC地址IP地址与MAC地址总结IP地址MAC地址计算机网络背景网络发展        是最开始先有的计算机,计算机后来因为多项技术的水平升高,逐渐的计算机变的小型化、高效化。后来因为计算机其本身的计算能力比较的快速:独立模式:计算机之间相互独立。    如:有三个人,每个人做的不同的事物,但是是需要协作的完成。    而这三个人所做的事是需要进行协作的,然而刚开始因为每一台计算机之间都是互相独立的。所以前面的人处理完了就需要将数据

  8. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

  9. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

  10. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

随机推荐