栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

文章目录
  • 前言
  • Spring简介
    • 何为AOP
    • 何为IOC
    • set注入
    • IOC本质
  • Spring Hello world
    • Hello world 细节
      • IOC创建对象
      • 对象赋值
      • 对象构造方法赋值
    • getBean创建对象细节
  • Spring 配置
    • 取别名 alias
    • Bean
    • import
  • 注入详谈
    • 基础类型注入
    • Map注入
    • 数组注入
    • 列表注入
    • 集合注入
    • Properties注入
    • 优化配置
    • Bean的作用域
  • 自动装配
    • 使用XML自动装配
  • Spring 注解
    • 注解自动装配(Autowired)
    • 基本注解
      • Component
        • 衍生注解
      • Value
    • Scope注解
  • JavaConfig
  • Spring AOP
    • SpringAPI接口实现
      • 导入依赖
      • 准备案例类
      • 进入配置文件
      • 准备测试
    • 自定义增强类
      • 自定义类
      • 修改配置文件
    • 使用注解实现
    • 环绕
  • 总结

前言

在此之前我先谈谈我的学习路线,我个人感觉是有点飘,不太可取的,但是也说明一下我为什么直接跳过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项目导入依赖,就不用多说了吧。



    4.0.0

    org.example
    Springframe
    pom
    1.0-SNAPSHOT
    
        spring-dome-01
    

    
        8
        8
    

    
        
            org.springframework
            spring-webmvc
            5.2.7.RELEASE
        
    


然后干啥创建写个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文件




    
        
        
       
                
    




然后进入测试

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,那么在这里的话注意到配置文件




    
        
        
       
                
    




这里有两个注意点

对象赋值

这个通过


来实现

对象构造方法赋值

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


2 . 变量属性



3.变量名直接赋值


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玩多了的老熟了。
这个简单回到那个配置文件




    
        
        
       
                
    
    
    




Bean

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


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

注入详谈

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

public class UserDomevalue {
    private String name;
    private String[] strings;
    private List list;
    private Set set;
    private Properties properties;
    private Map map;

}
基础类型注入

       
Map注入
  
            
                
            
        
        
数组注入

            
                Hello
                world
            
        
列表注入
 
            
                Hello
                World
            
        
集合注入
  
            
                Hello
                world
            
        
Properties注入
 
            
                world
            
        
优化配置

对于一些简单的注入我们还有更加好的选择,那就是P命名和C命名空间注入。
这个其实很简单,一个是针对参数的一个是针对构造方法传值的。
先导入两个玩意

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

那么现在直接看到这个

看到了不直接出来了。
这个用法很简单的,无非就是简化了一下。不用也可以就像先前的Django里面的Q对象。

Bean的作用域

当前基础我们就关注两个,单例,和原型模式。

单例模式(默认的)

xml

原型模式

xml

自动装配 使用XML自动装配

这玩意咋说呢,就是让Spring自己去根据上下文去寻找对应的值,然后去自己装配,也就是自动赋值,自动帮助我们完成赋值的工作不过这个显然只是适应于简单的操作。
根据名字自动装配。
xml
根据类型装配
xml
下面给出例子:

public class Head{}
public class Foot{}
public People{
	private Head head;
	private Foot foot;
	//get set方法省略
}

接下来在xml注册

  
  
  

那么此时就会自动装配了,这里是byname所以bean的id的值和people里面的变量的值相同,如果不同就装不了。
例如

 

此时就不行了。那么除此之外还可以通过注解实现。

Spring 注解

回到我们的XML配置问价,我们需要加入几个依赖。
完整的配置如下




  
  
    
  
  
  

注解自动装配(Autowired)

这个时候咱们回到那个People类

public People{
	@Autowired
	private Head head;
	@Autowired(required=false)
	private Foot foot;
	//表示这个玩意可以为空和下面的等价
	//public void setFoot(@Nullable Foot foot){
	//this.foot = foot;}
	//get set方法省略


}

不过这个也是有局限的,那就是老规矩被装配的bean的id需要和变量名一样(或者说能够找到)(需要装配的)
如果实在找不到还可以给个默认值

public People{
	@Autowired
	private Head head;
	@Autowired(required=false)
	@Qualifier(value="foot")
	private Foot foot;
	//表示这个玩意可以为空和下面的等价
	//public void setFoot(@Nullable Foot foot){
	//this.foot = foot;}
	//get set方法省略


}

所以在用这个的时候请注意环境!如果自动装配环境复杂就挂了。
那么与之类似的还有一个注解这个是Java自己的玩意不是Spring里面的,没有Spring环境也能用

@Rescurce
private Head head;
@Rescurce(name="head")//对应ID的值
private Head head;

区别是
Autowired 是默认通过bytype来实现的。
Rescource 是byname 和 bytyple(byname找不到时)实现的。

基本注解

现在回到前面的配置文件,现在如果我们想要让我们的其他的注解生效那么我们还要一个玩意(除了AOP上下文)看到配置文件。



	
    
    

Component

这个注解的作用是啥呢那简单举个例子。

@Component
public class Head{}
@Component
public class Foot{}
@Component
public People{
	private Head head;
	private Foot foot;
	//get set方法省略
}

等价于

  
  
  

id名字默认时类名的小写。
调用还是老规矩。

public class Test {

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

    }
}
衍生注解

这个主要时配合spring MVC三层架构的,功能和Component一样的,只是为了好区分。不过我这边 MVC大概率直接跳过,上Spring Boot,搞前后端分离所以后面我会重新学一下vue,MVC或者MVT看了人家的开发发现这样做是真的慢,而且耦合度太高!参考目White Hole 项目 .

三层架构嘛
Dao 层----> @Repository
Service ----> @Service
controller ----> @Controller
功能一样但是为了区分嘛!

Value

这个是啥呢,就是给默认值。

@Component
public class User{
	@Value("Huterox")
	public String name;
}

对于简单的还是好用的。

Scope注解

这个干啥的不就是作用域嘛!

@Component
@Scope("prototype")
//@Scope("singleton")
public class User{
	@Value("Huterox")
	public String name;
}

一般还是给值注入用注解吧,基础的可以用用注解,但是那个xml确实还是永远的神!

JavaConfig

这个是一个比较厉害的地方,官方说是不用依赖配置文件了。
不过这个玩意其实早就见过了,如果你看了前面的博文的话(我是直接先干Dao层的)我用mybatis plus的时候用了一个玩意叫做配置类。
MybatisPlus实现基本CURD&逻辑删除&代码生成(对标Django系列学习二)
不过这玩意还好挺简单的(其实我当时也没注意)
而且这玩意可是好玩多了。
看好了!
首先咱们老规矩搞个类叫User

@Component
public class User(){
	@Value("Huterox")
	private String name;
	//这里省略的get set方法
}

接下来是配置类

@Configuration
public class Config{
	@Bean
	public User getUser(){
		return new User();
	}
}

现在咱们获取这个类

public class MyTest{
	public static void main(String[] args){
	AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
	User user = (User)context.getBean("getUser");
	}
}

在这里先前还提到了目录扫描,那么在这里也是一样的有

@ComponentScan("com.Huterox.pojo")

此外我们也支持import引入另一个配置类,这个效果是和我们的配置文件的导入类似的。

@Configuration
@ComponentScan("com.Huterox.pojo")
@import(Config2.class)
public class Config{
	@Bean
	public User getUser(){
		return new User();
	}
}

这个中方式的话在spring boot好像挺常见的,至少在我先前玩mybatis plus的时候见了不少,基本上我就改了两个东西,一个是spring boot自己的配置文件,还有一个就是配置类。(不得不说我当时是真的刚,啥也不理解就开始怼,不过其实也没啥说白了玩的只是一个框架,暂时不清楚咱们按照规则来就好了,理解一下规则的规律就好了,有时间再补个票,像现在这样,而且现在说实话也不是了解真正的底层,这个不过是引入规则的规则罢了,也就是上级,再挖再挖再挖下去就是计算机底层了,这个没意义,咱们要学的还是框架咋个玩,怎么完好,相关的设计模式和核心思想)

Spring AOP

这个是Spring的一个比较重要的点,其实不管是Java还是python你要做个好玩的东西都用得到,只是在python里面实现这个相当简单,python装饰器了解一下,那么在Java当作其实页挺简单的,那么在spring当中实现这个也很简单,当然这个不需要像我们先前那样从InvocationHandler 工厂模式那里开始撸。

这里面怼几个概念

切面(ASPECT)
通知(Advice)
目标(Target)
代理(Proxy)
切入点(PointCut)
连接点(JoinPoint)

这个咱们也不管,这里我们直接用一个狂神的例子吧,说实话他说的东西很简单,很好理解,Spring一天搞定基础其实问题不大。
那么这里也是有三种方式的,一个一个来吧。

SpringAPI接口实现

以下步骤

导入依赖
        
            org.aspectj
            aspectjweaver
            1.9.7
        
准备案例类
public interface UserService {

   public void add();

   public void delete();

   public void update();

   public void select();

}



public class UserServiceImpl implements UserService{

   @Override
   public void add() {
       System.out.println("增加用户");
  }

   @Override
   public void delete() {
       System.out.println("删除用户");
  }

   @Override
   public void update() {
       System.out.println("更新用户");
  }

   @Override
   public void select() {
       System.out.println("查询用户");
  }
}




public class Log implements MethodBeforeAdvice {
	
   //method : 要执行的目标对象的方法 前置增强 
   //objects : 被调用的方法的参数
   //Object : 目标对象
   @Override
   public void before(Method method, Object[] objects, Object o) throws Throwable {
       System.out.println( o.getClass().getName() + "的" + method.getName() + "方法被执行了");
  }
}



public class AfterLog implements AfterReturningAdvice {
   //returnValue 返回值  后置增强
   //method被调用的方法
   //args 被调用的方法的对象的参数
   //target 被调用的目标对象
   @Override
   public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
       System.out.println("执行了" + target.getClass().getName()
       +"的"+method.getName()+"方法,"
       +"返回值:"+returnValue);
  }
}
进入配置文件

文件名字 bean1.xml




   
   
   
   

   
   
       
       
       
       
       
   


准备测试
public class Test1 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        UserServer userService = (UserServer) context.getBean("userService");
        userService.select();
    }
}
自定义增强类

也就是咱们的那个Log不去实现那个接口
这个主要区别就是自己动手实现一个配置类+配置文件不一样,但是其他的都是一样用的。
接下来还是几个步骤

自定义类
public class DiyAOP {
    public void before() {
        System.out.println("方法执行前");
    }

    public void after() {
        System.out.println("方法执行后");
    }
}
修改配置文件




    
    
        
        
        
        
     
    

测试
和前面的一样

@Test
public void test1() {
    ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");

    UserService userService = (UserService)context.getBean("userService");

    userService.add();
}
使用注解实现

我们拿到第二方法的例子。现在改一下

@Aspect
public class DiyAOP {
	@Before("execution(* com.huterox.Server.UserServerIm.*(..))")
    public void before() {
        System.out.println("方法执行前");
    }
	@Before("execution(* com.huterox.Server.UserServerIm.*(..))")
    public void after() {
        System.out.println("方法执行后");
    }
}

之后进入配置文件
一方面是注册一方面是进行注解支持的开启





之后就没有之后了,和前面一样使用。

环绕

那么目前已经介绍了before和after,基本够用了,但是这里还有一个什么环绕之类。
首先先看一个图:

这个我想应该很明白了吧!
那么咱们直接说怎么玩。

@Aspect
public class DiyAOP {
	@Before("execution(* com.huterox.Server.UserServerIm.*(..))")
    public void before() {
        System.out.println("方法执行前");
    }
	@Before("execution(* com.huterox.Server.UserServerIm.*(..))")
    public void after() {
        System.out.println("方法执行后");
    }
    @Around("execution(* com.huterox.Server.UserServerIm.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("环绕前");
        //获取签名
        //Signature signature = jp.getSignature();
        //System.out.println("signature:" + signature);

        //执行方法
        Object proceed = jp.proceed();

        System.out.println("环绕后");
    }

}
总结

到目前为止Spring的基础部分就OK了,那么后面其实还有的是Spring和mybatis mvc之间的组合,那么我这边选择的是Spring Spring Boot mybatis-plus 所以目前到这里其实就可以了。总的来说内容不多,具体这么玩还得看看那个大头 Spring boot 。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/336454.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号