Spring5框架 笔记总结(一)

Spring5框架 笔记总结(一),第1张

Spring5框架 笔记总结(一)

文章目录
  • 1. Spring5
    • 1.1 Spring5 概述
    • 1.2 其他框架
  • 2. Spring5 的相关jar包下载
  • 3. Spring5 IOC容器
    • 3.1 为什么要用IOC?
    • 3.2 什么是 IOC?
    • 3.3 IOC 接口
  • 2. Spring 实例
  • 3. Spring IOC创建对象的方式
    • 3.1 使用无参构造器创建对象(默认)
    • 3.2 有参数构造器创建对象
  • 4. Spring 配置
    • 4.1 别名
    • 4.2 Bean标签 的配置属性
    • 4.3 import标签
  • 5. 依赖注入
    • 5.1 什么是依赖注入?
    • 5.2 构造器注入
    • 5.3 Set方式注入(重点)
    • 5.4 p命名 和 c命名空间注入
      • 5.4.1 概述
      • 5.4.2 p-namespace p命名空间
      • 5.4.3 c-namespace c命名空间
  • 6. Bean 作用域(scopes)
    • 6.1 官方的bean 6个作用域
    • 6.2 singleton 单例模式(Spring 默认的模式)
    • 6.3 prototype 原型模式
    • 6.4 request,session ,application
  • 7. Bean 自动装配
    • 7.1 Bean的装配方式
    • 7.2 bean 隐式的自动装配(Autowired)
      • 7.2.1 Autowired 属性
      • 7.2.2 Autowired的 byName值
      • 7.2.3 Autowired的 byType值
  • 8. Spring的注解 实现自动装配
  • 9. java自带的注解 实现自动装配
  • 10. Spring 注解开发
    • 10.1 四个注解的使用
    • 10.2 @Component的衍生注解
    • 10.5 @Value注解的使用
    • 10.4 @Scope注解 作用域的使用
    • 10.5 总结 xml和注解 的优劣

1. Spring5 1.1 Spring5 概述

Spring 是轻量级的开源的JavaEE框架。

Spring 可以解决企业应用开发的复杂性。

Spring 有两个核心部分: IOC(Inversion of Control, 控制反转) 和 AOP( Aspect Oriented Programming , 面向切面编程)

Spring是分层的Java SE/EE应用 full-stack 轻量级开源框架,以IOC和AOP为内核。


IOC(Inversion of Control, 控制反转) : 把创建对象过程交给spring进行。

AOP(Aspect Oriented Programming , 面向切面编程):不修改源代码进行功能增强。


Spring的特点:

  • 方便解耦,简化开发(将对象间的依赖关系交由Spring进行控制,避免过度耦合)。
  • AOP编程支持。
  • 方便程序的测试。
  • 方便集成整合各种优秀框架(Struts,Hibemate等)。
  • 方便进行事务 *** 作(Spring ,通过声明式方式灵活的进行事务管理)。
  • 降低Java API的开发难度。
1.2 其他框架

SSH框架 : Struct2 + Spring + Hibernate(自动)
SSM框架 : SpringMVC + Spring + Mybatis(半自动)

学习顺序:

Spring Boot

  • 一个快速开发的脚手架。
  • 基于SpringBoot可以快速的开发单个微服务。

Spring Cloud

  • Spring Cloud 是基于Spring Boot实现的,用来管理它的。
2. Spring5 的相关jar包下载

Spring5下载相关jar包:https://spring.io/projects/spring-framework#learn

注意GA 和 snapshot的区别:

General Availability,正式发布的版本。


想要下载其他版本的可以访问该地址:

https://repo.spring.io/ui/native/release/org/springframework/spring


Spring大体上的一个模块框架:

Core Container:核心容器 ,这个是最基础要掌握的,上面的 *** 作都是基于核心容器来实现的。

3. Spring5 IOC容器 3.1 为什么要用IOC?

做程序讲究高内聚,低耦合。

一般我们的声明对象调用方法,都是new 对象,调用该对象的方法,但是如果我们修改了对象方法的名字,那么一下子啊就要改所有调用该方法的对象,这样耦合度太高了。

对于上面这种情况可以通过工厂模式来达到一个解耦效果:(通过UserFactory,大大降低了UserService和UserDao直接的耦合。)

但是,工厂模式下的耦合度还不是最低的,还可以通过IOC来实现这降低耦合!!

3.2 什么是 IOC?

IOC控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理。

没有IOC冲虚,一系列的对象创建都是由程序自己完成,控制反转后将对象的创建转移给第三方,也就是获得依赖对象的方式反转了。

使用IOC目的:为了耦合度降低。


IOC的底层原理由三个部分组成:

  • xml解析。
  • 工厂模式。
  • 反射

也就是说学spring之前,java的工厂模式和java反射都要知道!


IOC总结:

采用xml方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解) 并通过第三方去生产或获取特定的对象方式。在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(Dependency Injection , ID)

3.3 IOC 接口

IOC思想基于IOC容器完成,IOC容器底层就是对象工厂。

spring提供了实现IOC容器的两种方式:(也就是两个接口)

  • BeanFactory接口:该接口是IOC容器最基本的实现方式,是spring内部自带的接口,不提供开发人员进行使用。
  • ApplicationContext接口:它是BeanFactory接口的子接口,提供了更多更强大的功能,一般是开发人员使用的。

上面两个都能实现IOC容器。

2. Spring 实例

所谓的IOC就是:对象由Spring来创建,管理,装配

创建一个maven项目,在pom.xml中导入spring的相关依赖:


   
       org.springframework
       spring-web
       5.3.9
   

如下案例:

创建一个beans的xml文件:




    
    
    
        
        
        
        
    

在maven中的main/java中创建hello.java类

package com.itholmes.pojo;


public class Hello {
    private String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

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

在maven的test/java中测试能否通过xml文件创建管理类:


import com.itholmes.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Mytest {
    public static void main(String[] args) {
        //获取spring的上下文对象context,也就是获取ApplicationContext:拿到Spring的容器。
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        //我们的对象现在都在Spring中管理了,我们要使用,直接去里面取出来调用就可以了。
        Hello hello = (Hello) context.getBean("hello");

        System.out.println(hello.toString());
    }
}

bean属性ref的使用:


注意:idea提示创建上下文参数

上面的意思可以理解为创建一个新的程序上下文参数,配置该文件到spring项目中去。

完成上面 *** 作,我们在类中可以看到相关的标签已经导入进来:

3. Spring IOC创建对象的方式 3.1 使用无参构造器创建对象(默认)

IOC在配置xml文件控制反转时,创建对象也是分无参数和有参数的,默认的就是无参数构造器。

3.2 有参数构造器创建对象

方式一,index下标的方式:


     
     


方式二:通过使用类型创建,不建议使用!


    
    
    


第三种:通过使用参数名和name属性来传递参数,建议使用。


    
    


我们平时说的spring容器就是下面的context:

 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

总结:在配置文件加载的时候,容器中管理的对象就已经初始化了。

这句话意思不难理解,就是我们所有配置在beans中的内容,都将会在new ClassPathXmlApplicationContext(“beans”); 执行完后将beans中所有的配置的类对象,全部加载创建完毕。之后我们想调用谁就调用谁,也就是在一个容器当中想用谁就用谁。

4. Spring 配置 4.1 别名

alias别名:就是给user起了个别名,同样我们可以使用别名获取到这个对象。


4.2 Bean标签 的配置属性

对于Bean标签的配置属性,基本的如下:


    

4.3 import标签

import标签,一般用于团队开发使用,他可以将多个配置文件,导入合并为一个。


import标签功能很强大,如果遇到相同的内容,就会覆盖一起,别名也是一样的。

5. 依赖注入 5.1 什么是依赖注入?

在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(Dependency Injection , ID)

5.2 构造器注入

构造器,在第三节的Spring IOC创建对象的方式中已经说明。

5.3 Set方式注入(重点)

依赖注入:Set注入

在这解释一下为什么set注入,因为它必须要用到setXxx()方法因此这样命名。

  • 依赖:bean对象的创建依赖于容器。
  • 注入:bean对象中的所有属性,由容器来注入!

set注入效果如下:




    
        
    

    

        

        
        

        
        

        
        
            
                三国演义
                水浒传
                红楼梦
                西游记
            
        

        
        
            
                听歌
                玩游戏
                打篮球
            
        

        
        
            
                
                
            
        

        
        
            
                123
                456
                789
            
        

        
        
            
        
        
        

        
        
            
                root
                root
                jdbc:mysql://localhost:3306/
                com.mysql.jdbc.Driver
            
        

    


student类:

package com.itholmes.pojo;


import java.util.*;

public class Student {

    private String name;
    private Address address;
    private String[] books;
    private List hobbys;
    private Map card;
    private Set game;
    private String wife;
    private Properties info;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String[] getBooks() {
        return books;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public List getHobbys() {
        return hobbys;
    }

    public void setHobbys(List hobbys) {
        this.hobbys = hobbys;
    }

    public Map getCard() {
        return card;
    }

    public void setCard(Map card) {
        this.card = card;
    }

    public Set getGame() {
        return game;
    }

    public void setGame(Set game) {
        this.game = game;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", address=" + address.toString() +
                ", books=" + Arrays.toString(books) +
                ", hobbys=" + hobbys +
                ", card=" + card +
                ", game=" + game +
                ", wife='" + wife + ''' +
                ", info=" + info +
                '}';
    }
}

Address类:

package com.itholmes.pojo;


public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + ''' +
                '}';
    }
}

测试类MyTest:


import com.itholmes.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student s = (Student) context.getBean("student");
        System.out.println(s.toString());
        //Student{name='张三', address=Address{address='上海'}, books=[三国演义, 水浒传, 红楼梦, 西游记], hobbys=[听歌, 玩游戏, 打篮球], card={学号=123, 姓名=itholmes}, game=[123, 456, 789], wife='null', info={password=root, url=jdbc:mysql://localhost:3306/, driver=com.mysql.jdbc.Driver, username=root}}

    }
}

不同的类型,通过不同的方式进行注入!

5.4 p命名 和 c命名空间注入 5.4.1 概述

官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html

p命名和c命名如下:

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
5.4.2 p-namespace p命名空间

p命名空间注入,可以直接注入属性的值。(这里的p就是property属性的意思

userbeans.xml文件:




    
    


User.java类:

package com.itholmes.pojo;


public class User {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }

}

MyTest02.java测试类:


import com.itholmes.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest02 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user = context.getBean("user",User.class); //在后面添加上了User.class类型后,就不用每次都强转了。
        System.out.println(user.toString());
        //User{name='张三', age=18}
    }
}

这里我们可以通过使用测试类验证,p命名是否注入成功。

5.4.3 c-namespace c命名空间

这里就是传递构造器的内容了,注意如果我们添加了有参构造器,那么无参构造器也要添加,不然前面的默认无参构造器的bean会报错!

c命名空间的xml文件:




    
    
	

User.java类(比起上添加了有参和无参构造器):

package com.itholmes.pojo;


public class User {
    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }

}

同样进行MyTest02.java测试:


import com.itholmes.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest02 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user = context.getBean("user2",User.class); //在后面添加上了User.class类型后,就不用每次都强转了。
        System.out.println(user.toString());
        //User{name='itholmes', age=18}
    }
}

c命名空间就是设置有参构造器的,很容易理解。


注意:p命名和c命名空间不能直接使用,需要导入xml约束,所谓的约束就是下面的这段代码:

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
6. Bean 作用域(scopes) 6.1 官方的bean 6个作用域

在官方上面bean的作用域有六种:

6.2 singleton 单例模式(Spring 默认的模式)

singleton意思是单例。

Spring默认就是单例模式。

通过scope属性设置为singleton:


6.3 prototype 原型模式

原型模式和我们认识的多例模式差不多。

scope属性值设置为prototype就可以了。


多线程一般使用原型模式,单线程一般使用单例模式,看情况使用。

MyTest02.java 测试类:


import com.itholmes.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest02 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user = context.getBean("user2",User.class); //在后面添加上了User.class类型后,就不用每次都强转了。
        User user2 = context.getBean("user2",User.class); //在后面添加上了User.class类型后,就不用每次都强转了。
        //原型模式就是不同的对象了。
        System.out.println(user.hashCode()+","+user2.hashCode());
        System.out.println(user == user2);
        //1709366259,1335298403
        //false
    }
}

可以看到上面的结构无论是hashcode还是判断都是不同的对象。
也就是每次从容器中获得时,都会获得一个新对象。

6.4 request,session ,application

request,session ,application这些个只能在web开发中使用。

就是Servlet的三大域对象一样的。

  • 设置为request:对象只能在一次请求内存活。
  • 设置为session:对象只能在一次会话内存活。
  • 设置为application:对象在项目开始到项目关闭存活。
7. Bean 自动装配 7.1 Bean的装配方式

自动装配是Spring满足bean依赖的一种方式。

Spring会在上下文中自动寻找,并自动给bean装配属性。

Spring中有三种装配的方式:

  • 在xml中显示的配置。(前面)
  • 在java中显示配置。
  • 隐式的自动装配bean。(重点!)
7.2 bean 隐式的自动装配(Autowired) 7.2.1 Autowired 属性

官方给的是:自动装配Autowired。

通过Autowired属性设定。

7.2.2 Autowired的 byName值

byName值:会自动在容器上下文中查找,和自己对象setXxx方法后面的Xxx值对应的beanid




    
    

	
	
	
	
	

弊端:必须和set后面的名字相同,也就是唯一才能自动装配到。

7.2.3 Autowired的 byType值

byType值:会自动在容器上下文中查找,和自己对象属性类型相同的bean。




    
    

	
	
	


弊端:type类型必须唯一,不然会直接报错的,同样就算设置的bean没有id,依然能够自动装配,因为是根据类型来的。。

8. Spring的注解 实现自动装配

注解仅仅是JDK1.5以上支持的版本,在Spring中2.5 版本就支持注解了。

使用注解前提:

  • 导入约束。
  • 配置注解的支持。

官方的注解配置如下:




    

	



第一步,添加约束:

添加一个约束:

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

两个约束的支持就是xsi:schemaLocation中的:

http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd

第二步,添加注解支持:

context:annotation-config,开启注解的支持。


设置好上面的约束后,就可以在对象类中设置@Autowired注解:
(被注解注释的属性必须与xml文件中的bean的id属性相同)


@Autowired注解注意事项:

  • 使用了@Autowired注解后,连set方法都是不需要的!
  • @Autowired注解直接在属性上使用即可!也可以在setXxx方法上使用。
  • 使用@Autowired我们可以不用编写setXxx方法了,前提是你这个自动装配的属性在IOC(Spring)容器中存在,且bean的id值名字必须相同!

@Nullable注解使用:

@Nullable 某个字段标记了这个注解,说明这个字段可以为null!

@Autowired注解源码如下:

public @interface Autowired {
    boolean required() default true;
}

因此,它是有一个required属性的设置,设个属性和@Nullable注解差不多来定义能否为null的。

如果显示定义了Autowired的required属性为false,说明这个对象可以为null;定义为true,就不能为空!


@Autowired注解:

可以自动进行装配匹配xml文件中的bean效果,不用设置property属性了。但是如果有多个bean名字差不多,这是Autowired就会报错了!原因就是不确定找不到是哪一个。如下:

@Qualifier注解:

这个时候就需要@Qualifier(value=“xxx”)来指定xml配置文件中的bean属性了。

代码效果如下:

package com.itholmes.pojo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.lang.Nullable;


public class People {

    //如果显示定义了Autowired的required属性为false,说明这个对象可以为null;定义为true,就不能为空!。
    @Autowired
    @Qualifier(value = "cat222")
    private Cat cat;

    @Autowired
    @Qualifier(value = "dog222")
    private Dog dog;

    private String name;


    public People() {
    }

    //@Nullable注解:name为空也不会报错!
    public People(String name) {
        this.name = name;
    }

    public Cat getCat() {
        return cat;
    }

    public Dog getDog() {
        return dog;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "People{" +
                "cat=" + cat +
                ", dog=" + dog +
                ", name='" + name + ''' +
                '}';
    }
}



    
    

    
    
    
    

    


确定好前后对应即可。

9. java自带的注解 实现自动装配

@Resource注解:

同样,在没有多个bean的相同类型时,@Resource也是可以实现自动装配,name属性也可以指定bean的属性值id。

注意这个Resource注解是javax.annotation.Resource下的,不是spring的东西。

开发中,我们常用的就是@Autowired注解和@Resource注解实现,前者最多。


@Resource和@Autowired的区别:

  • 都是用来自动装配的,都可以放在属性字段上。
  • @Autowired通过byType的方式实现,如果设置了@Qualifier(value=“xxx”)则用byname实现,而且必须要求该对象bean存在!
  • @Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现,如果两个都找不到就会报错!。
  • 执行顺序不同:@Autowired先是通过byType实现,@Resource先是通过byname实现
10. Spring 注解开发 10.1 四个注解的使用

上面说过的注解如下:

@Autowired:spring自动装配,配合@Qualifier(value=“xxx”)来使用。

@Nullable:字段标记了这个注释,说明这个字段可以为null。

@Resource:java自带的自动装配通过名字,类型。


在介绍一个@Component注解:

@Component:Component英文意思就是组件的意思。

这个注解相当于我们自定义的bean标签,例如:


注意使用@Component注解时,必须指定要扫描的包:

换句话说,我们不用自己去xml文件定义对象bean标签了。

他还有一个@Value(“xxx”)注解可以给属性变量添加值,我们之前的@Autowired是给自己创建的引用实例类来自动装配的。

User.java类:

package com.itholmes.dao;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

//@Component英文意思就是组件的意思。
//等价于
@Component
public class User {

    //@Value等价于它:
    @Value("itholmes")
    public String name;

    //也可以注入到set方法上面
    //@Value("itholmes")
    public void setName(String name) {
        this.name = name;
    }

}

beans.xml如下:




    
    

    


测试类:


import com.itholmes.dao.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user", User.class);
        System.out.println(user.name);
    }

}
10.2 @Component的衍生注解

@Component有几个衍生注解,在web开发中,会按照mvc三层架构分层。

  • dao层 : @Repository
  • service层:@Service
  • controller层:@Controller

换句话说这四个注解的功能是相同的!都是代表某个类注入到Spring容器中,装配Bean。

注意,不要忘记扫描包的的声明!

10.5 @Value注解的使用

上面我们通过@Autowired注解来自动装配指定实例类的 *** 作。

我们还可以通过@Value来给类中的属性变量设置值。

10.4 @Scope注解 作用域的使用

@Scope就是对应上面我们设定scope属性的注解,同样值常用的就是singleton单例模式,prototype原型模式。

Scope也就是作用域。

10.5 总结 xml和注解 的优劣

xml 与 注解:

  • xml是万能的,适用于任何场合!维护起来简单方便。
  • 注解是定义到类中,因此不是被自己注解的类是不能够使用的。而且维护起来相对复杂一些。

最佳方案如下:

  • xml用来管理bean。
  • 注解只负责完成属性的注入。
  • 我们在使用的过程中只需要注意一个问题,必须让注解生效,也就是开启注解支持,也就是下面内容:



    
    
    


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5685920.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存