分分钟搞定Spring5轻轻松松一遍过

Posted HUTEROX

tags:

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

前言

在此之前我先谈谈我的学习路线,我个人感觉是有点飘,不太可取的,但是也说明一下我为什么直接跳过Java 的 web基础,也就是severlet 和 jsp这一块,直接上spring全家桶而且上的时候还是先从Dao层也就是 mybatis 和 mybatis-plus( 主要)这一块开始哈。首先如果你一开始就关注了我,也就是我从高二开始的时候第一次从CSDN发布了博客,那个时候我是在玩爬虫的,对于很多的请求库和网络请求的一些细节和网站运作我是有一定了解的,当然那个时候我更多的技术倾向是发送请求,爬虫反反爬,请求参数抓取,爬虫稳定,爬取效率这一块。当然高三那一年没怎么玩了毕竟学习嘛,后来大一我一个学期玩的是网络安全相关的东西,当然也是接触了很多奇奇怪怪的东西,这一块我暂时没有深挖下去,因为第一是面向监狱编程不可取,二是遇到了瓶颈,我发现我一个学期下来都还只是在玩玩框架,对于想要渗透的对象一无所知(并不是很清楚),我没有去理解底层(当然现在也没有),只知道这个怎么用,至于为什么这样我回答的很模棱两可。后来就是玩了玩Java一开始就是玩玩安卓,哪个感兴趣我玩哪个,我没有按照网上给的路线走,然后嘛,后面都出鸿蒙了是吧…客户端还是不太稳的而且太考验美感了!之后就是我又回到了python 路线,当时学的还算认真 起码手撸了一个 Http 服务器(不过那是寒假就发生的事情了,我重新捡起的时候是暑假了)然后就是恶补前面的内容然后上Django,随便研究了一下Django可能存在的问题(渗透),再后来就是数学建模比赛了,我暂时就停止了(其实当时也差不多了只是我本来打算做个网站的只是暂时停了)。之后大二回到学校我忙完了一些事情,不过都一个月了国庆的时候紧急花了五天做出了一个whitehole,当然也停了,现在是打算赶紧学然后用Java重构,之后再在两个框架之间不断更新完善。所以在基础方面我自认为我是可以跳的,大不了补回来呗。然后就是我目前选择的搭配就是 Spring springboot mybatisplus 至于mvc慢慢来看看呗,玩框架不谈设计思想只谈承上启下我觉得是很可笑的,至于底层很多人所谓的底层是另一个框架(搞不懂 手动狗头)…

Spring简介

记住两句话
1.前身 interface21 在 2002 年推出
2.控制反转(IOC) 和 面向切面(AOP)
其他的就不说了,我也记不住!
那么我们这块就先说说啥叫 IOC 和 AOP

何为AOP

首先AOP这玩意老盆友了,不管是Java还是python天天用!
这边我都有博客说明!

Java Dome(AOP模式回顾小Dome)
@高级语法python(装饰器)语法小糖豆。

何为IOC

set注入

在此之前先来谈谈注入(开发模式)这个是IOC的前身。
咱们直接演示代码吧,老套路了一看就会。
举个例子:
模拟点菜,在现实生活中点菜的时候有一个菜单,菜单时固定的,但是厨师不是.现在菜单就好比接口,不会轻易变动,但是厨师却可以不断变动.现在假设有两个厨师,都会做菜单上的菜.然后顾客可以随意跟换厨师做菜.

菜单接口:`

public interface Foodmean {
	void chaojidan();
	void chaoxihongshi();
}

厨师类实现接口功能

1.AmericanCook

public class AmericanCook implements Foodmean{
	public void chaojidan(){
		System.out.println("AmericanCook is cooking chaojidan");
	}
	public void chaoxihongshi(){
		System.out.println("AmericanCook is cooking chaoxihongshi");
	}
}

2.ChineseCook

public  class Chinesecook implements Foodmean {
	public void chaojidan(){
		System.out.println("ChineseCook is cooking chaojidan");
	}
	public void chaoxihongshi(){
		System.out.println("ChineseCook is cooking chaoxihongshi");
	}

}

顾客类
这里的话当然少不了Food mean
其实接口的使用往往和多态离不开

public class Customer {
	private Foodmean foodmean;
	
	public Customer(){
		
	}
	public Customer(Foodmean foodmean){
		this.foodmean = foodmean;
	}
	public Foodmean getFoodmean() {
		return foodmean;
	}
	public void setFoodmean(Foodmean foodmean) {
		this.foodmean = foodmean;
	}
	public void order(){
		this.foodmean.chaojidan();
		this.foodmean.chaoxihongshi();
	}
}

调用测试:

public class Text {

	public static void main(String[] args) {
//		Foodmean foodmean = new AmericanCook();
		Foodmean foodmean = new Chinesecook();
 		Customer xiaomingCustomer=new Customer();
		xiaomingCustomer.setFoodmean(foodmean);
		xiaomingCustomer.order();
	}
}

现在换一下

Foodmean foodmean = new AmericanCook();

这个就是我们经常用的(新手时期)
那么后面IOC是啥呢,就是这样:
我们再定义一个类

public class Cooker{
	private Foodmean foodmean;
	
	public void setMean(Foodmean foodmean){
	this.foodmean = foodmean;
}
	public Foodmean getMean(){
	return this.foodmean;}
}

那么接下来我们的Test就这样写

public class Text {

	public static void main(String[] args) {
		Cooker cooker  = new Cooker();
 		Customer xiaomingCustomer=new Customer();
		xiaomingCustomer.setFoodmean(cooker.setMean(new Chinesecook()));
		xiaomingCustomer.order();
	}
}

那么现在你想要哪个就new 哪一个。

IOC本质

那么这个就是所谓的反转,所谓的IOC,一直设计思想。顺转是什么那就是控制权在我们手上。那这句话又怎么理解呢,也就是先前我们是直接要用哪个直接New 一个,但是现在我们使用了一个第三方提供了一个set方法,我们这个时候就只需要通过它来换对应的实现,一方面我们可以解耦合,另一方面在一定程度下可以动态的切换模式,例如功能切换之类的。这个其实没啥好说的了,哪一次的我做的小玩意我没用过这种类型的设计思想(只是我当初不知道叫啥!)

那么这个Spring的IOC容器是啥,一句话总结若干个符合业务的类似于前面例子Cooker类的集合然后再结合我们的工厂模式和注解或者xml去方便调用实现。很高级看起来!
那么这边在Spring实现是通过xml或者注解实现的。这边我忘了写一篇如何结合AOP模式手撸一个注解的博文了,有需要评论区留言。

Spring Hello world

ok,先说明一下啊Spring只是做个了解罢了,过一遍而已。
创建Maven项目导入依赖,就不用多说了吧。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>SpringFrame</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>spring-dome-01</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
    </dependencies>

</project>

然后干啥创建写个Hello world

package com.huterox.pojo;

public class Hello {
    private String Hello;

    public String getHello() {

        return Hello;
    }

    public void setHello(String hello) {
        Hello = hello;
    }

    public Hello(String hello) {
        Hello = hello;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "Hello='" + Hello + '\\'' +
                '}';
    }
}

这个文件放在哪不用多说了吧。
然后是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="Hello" class="com.huterox.pojo.Hello">
        <constructor-arg value=""/>
        <property name="Hello" value="Hello world"/>
       
                
    </bean>
<!--    <bean id="Hello" class="com.huterox.pojo.Hello"/> 不赋值只是注册-->
<!--        <property name="Hello" value="Hello world"/> ref="具体对象名,bean的id名字"-->

</beans>

然后进入测试

import com.huterox.pojo.Hello;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

   public static void main(String[] args) {
       ClassPathXmlApplicationContext Context = new ClassPathXmlApplicationContext("Aplication.xml");
       Hello hello = (Hello) Context.getBean("Hello");
       System.out.println(hello.getHello());

   }
}

突然发现这个套路和安卓挺像的。
至于他为什么能够实现的原理嘛,其实很简单的,看前面那个AOP的那个博客你就能搞明白,只不过这里换了一下xml文件,这个xml文件怎么搞也很简单,有需要评论区说明,看心情更新。当然那只是原理,实现起来它分了很多层。

Hello world 细节

IOC创建对象

我们这边其实就是一个IOC的演示在Spring,那么在这里的话注意到配置文件

<?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="Hello" class="com.huterox.pojo.Hello">
        <constructor-arg value=""/>
        <property name="Hello" value="Hello world"/>
       
                
    </bean>
<!--    <bean id="Hello" class="com.huterox.pojo.Hello"/> 不赋值只是注册-->
<!--        <property name="Hello" value="Hello world"/> ref="具体对象名,bean的id名字"-->

</beans>

这里有两个注意点

对象赋值

这个通过

<property name="Hello" value="Hello world"/>

来实现

对象构造方法赋值

<constructor-arg value=""/>

这里有三种方式给值。
1.下标

<constructor-arg index="0" value=""/>

2 . 变量属性

<constructor-arg type="int" value=""/>
<constructor-arg type="java.lang.String" value=""/>

3.变量名直接赋值

<constructor-arg name="Hello" value="Hello world"/>

getBean创建对象细节

这个其实在加载配置文件的时候会把所有的对象都进行创建,也就是说在加载配置文件的时候里面所有的注册了的类都会被实例化,之后通过getbean方法获取其中某一个。
此外getbean获取相同的对象时获取的是同一个对象。

        ClassPathXmlApplicationContext Context = new ClassPathXmlApplicationContext("Aplication.xml");
        Hello hello = (Hello) Context.getBean("Hello");
        Hello hello1 = (Hello) Context.getBean("Hello");
        System.out.println(hello==hello1);
        

这个值为真 ,那原因的话是因为我们目前使用的是单例模式。(这个可以改)

Spring 配置

取别名 alias

这个Linux玩多了的老熟了。
这个简单回到那个配置文件

<?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="Hello" class="com.huterox.pojo.Hello">
        <constructor-arg value=""/>
        <property name="Hello" value="Hello world"/>
       
                
    </bean>
    <alias name="Hello" alias="H"/>
    <!-- 把 Hello 别名为 H 到时候直接读取 H 也是一样的 -->
<!--    <bean id="Hello" class="com.huterox.pojo.Hello"/> 不赋值只是注册-->
<!--        <property name="Hello" value="Hello world"/> ref="具体对象名,bean的id名字"-->

</beans>

Bean

这个就不用多说了,前面都演示多少回了
这里补充一下

<bean id="Hello" class="com.huterox.pojo.Hello" name="H“>

这里name直接取别名

<bean id="Hello" class="com.huterox.pojo.Hello" name="H,W“>

取多个别名,H ,W
可以用 ,和 空格 分号 分隔别名

import

导入多个配置文件参考 nginx的 include

<import resource="beans.xml"/>

这个就好了,如果导入的文件的bean有重复的话他会自己选择一个所以注意重复问题,取个好点的别名。

注入详谈

这个注入前面也铺垫了。什么是注入也应该看明白了。
不过前面没有好好说清楚,那么在这里就详细说一说,咱们这个主要是啥,是值注入,也就是针对变量赋值。
现在咱们定义一个类,现在依次通过xml进行赋值

public class UserDomeValue {
    private String name;
    private String[] strings;
    private List<String> list;
    private Set<String> set;
    private Properties properties;
    private Map<String,String> map;

}

基础类型注入

<property name="name" value="UserDome"/>
       

Map注入

  <property name="map">
            <map>
                <entry key="Hello" value="world"/>
            </map>
        </property>
        

数组注入

<property name="strings">
            <array>
                <value>Hello</value>
                <value>world</value>
            </array>
        </property>

列表注入

 <property name="list">
            <list>
                <value>Hello</value>
                <value>World</value>
            </list>
        </property>

集合注入

  <property name="set">
            <set>
                <value>Hello</value>
                <value>world</value>
            </set>
        </property>

Properties注入

 <property name="properties">
            <props>
                <prop key="Hello">world</prop>
            </props>
        </property>

优化配置

对于一

以上是关于分分钟搞定Spring5轻轻松松一遍过的主要内容,如果未能解决你的问题,请参考以下文章

「深度学习一遍过」必修3:Pytorch数据读取——使用Dataloader读取Dataset

「深度学习一遍过」必修25:基于DCGAN的Image Production

「深度学习一遍过」必修6:利用迁移学习快速提升模型性能

「深度学习一遍过」必修24:基于UNet的Semantic Segmentation

「深度学习一遍过」必修25:基于DCGAN的Image Production

「深度学习一遍过」必修24:基于UNet的Semantic Segmentation