Spring学习笔记(篇一)

代码地址: https://github.com/Zhuyaqiang/spring-study

目录

  • 1 Spring
    • 1.1 简介
    • 1.2 优点
    • 1.3 组成
    • 1.4 扩展
  • 2 IoC理论推导
    • 2.1 示例
    • 2.2 IoC本质
  • 3 HelloSpring
    • 3.1 控制反转
  • 4 IoC创建对象的方式
  • 5 Spring配置
    • 5.1 别名
    • 5.2 Bean的配置
    • 5.3 import
  • 6 依赖注入
    • 6.1 构造器注入
    • 6.2 Set方式注入(重点)
    • 6.3 拓展方式注入
    • 6.4 bean的作用域
  • 7 Bean的自动装配
    • 7.1 测试
    • 7.2 ByName自动装配
    • 7.3 ByType自动装配
    • 7.4 使用注解自动装配
      • 7.4.1 小结
  • 8 使用注解开发
    • 8.1 bean
    • 8.2 属性如何注入
    • 8.3 衍生注解
    • 8.4 自动装配
    • 8.5 作用域
    • 8.6 小结
  • 9.使用Java的方式配置Spring

1 Spring

1.1 简介

  • Spring框架的目的是解决企业应用开发的复杂性, 使现有的技术更加容易使用, 整合了现有的技术框架
  • SSM: SpringMVC + Spring + Mybatis

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webmvcartifactId>
    <version>5.2.4.RELEASEversion>
dependency>

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-jdbcartifactId>
    <version>5.2.4.RELEASEversion>
dependency>

1.2 优点

  • Spring是一个开源的免费的框架(容器)
  • Spring是一个轻量级的、非入侵式的框架
  • 控制反转(IOC), 面向切面编程(AOP)
  • 支持事务的处理, 对框架整合的支持

1.3 组成

1.4 扩展

  • SpringBoot
    • 一个快速开发的脚手架
    • 快速开发单个微服务
    • 约定大于配置
  • SpringCloud
    • 基于SpringBoot实现

2 IoC理论推导

2.1 示例

  1. UserDao接口
  2. UserDaoImpl实现类
  3. UserService业务接口
  4. UserServiceImpl业务实现

原业务中, 用户的需求可能会影响原来的代码, 需要根据用户的需求去修改原代码

使用Set接口实现, 发生了革命性的变化

    private UserDao userDao;

    // 利用set动态实现值的注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
  • 之前程序是主动创建对象, 控制权在程序员手上.
  • 使用set注入后, 程序不再具有主动性, 而是变成了被动地接收对象

从本质上解决了问题, 程序员不用管理对象的创建, 系统的耦合性大大降低, 可以专注业务实现. 是IoC的原型

2.2 IoC本质

  • 控制反转IoC是一种设计思想, 依赖注入DI是实现IoC的一种方法, 所谓控制反转就是获得以来对象的方式反转了
  • 控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式. 在Spring实现控制反转的是IoC容器, 其实现方法是依赖注入

3 HelloSpring

3.1 控制反转

  • 传统应用程序的的对象是由程序本身控制创建的, 使用Spring后, 对象是由Spring来创建的
  • 程序本身不创建对象, 而变成被动地接收对象
  • 依赖注入是使用set进行注入
  • IoC: 对象由Spring来创建, 管理, 装配

4 IoC创建对象的方式

  • 默认使用无参构造创建对象

  • 使用有参构造创建独享

    1. 下标赋值

      <bean id="user" class="com.zyq.pojo.User">
          <constructor-arg index="0" value="zyq">constructor-arg>
      bean>
      
    2. 类型赋值(不建议使用)

      <bean id="user" class="com.zyq.pojo.User">
          <constructor-arg type="java.lang.String" value="zzz">constructor-arg>
      bean>
      
    3. 参数名赋值

      <bean id="user" class="com.zyq.pojo.User">
          <constructor-arg name="name" value="yqq">constructor-arg>
      bean>
      
  • 总结: 配置文件加载的时候, 容器中管理的对象就已经初始化了, 且只有一份

5 Spring配置

5.1 别名


<alias name="user" alias="dfsfdsfsd">alias>

5.2 Bean的配置


<bean id="userT" class="com.zyq.pojo.UserT" name="user2 u2, u3; u4">
    <property name="name" value="啦啦啦">property>
bean>

5.3 import

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

假设项目中有多人开发, 负责不同的类开发, 不同的类需要注册在不同的bean中, 可以利用import将所有人的beans.xml合并为一个总的配置文件

<import resource="beans.xml">import>
<import resource="beans2.xml">import>

6 依赖注入

6.1 构造器注入

6.2 Set方式注入(重点)

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

【环境搭建】

对应spring-04-di

  1. 复杂类型

    public class Address {
        private String address;
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    }
    
  2. 真实测试环境

    public class Student {
        private String name;
        private Address address;
        private String[] books;
        private List<String> hobbys;
        private Map<String, String> card;
        private Set<String> games;
        private Properties info;
        private String wife;
    }
    
  3. beans.xml

    
    <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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <bean id="student" class="com.zyq.pojo.Student">
            
            <property name="name" value="zyq">property>
        bean>
    
    beans>
    
  4. 测试类

    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Student student = (Student) context.getBean("student");
            System.out.println(student.getAddress());
        }
    }
    

6.3 拓展方式注入

可以使用p命名空间和c命名空间进行注入


<bean id="user" class="com.zyq.pojo.User" p:name="zyq" p:age="18">bean>

<bean id="user2" class="com.zyq.pojo.User" c:age="18" c:name="qqq">bean>

注意点: p命名和c命名空间, 需要导入xml约束

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

6.4 bean的作用域

  • 单例模式(Spring默认机制):

    <bean id="user2" class="com.zyq.pojo.User" c:age="18" c:name="qqq" scope="singleton">bean>
    
    
  • 原型模式: 每次从容器中get的时候, 都会产生一个新对象

    <bean id="user2" class="com.zyq.pojo.User" c:age="18" c:name="qqq" scope="prototype">bean>
    
    
  • 其余的和request, session, application. 只能在web开发中使用到

7 Bean的自动装配

  • 自动装配是Spring满足bean依赖的一种方式
  • Spring会在上下文中自动寻找, 并自动给bean装配属性

在Spring中有三种装配方式

  1. xml中显式配置
  2. java中显式配置
  3. 隐式的自动装配bean(重要)

7.1 测试

对应spring-05-Autowired

7.2 ByName自动装配


<bean id="people" class="com.zyq.pojo.People" autowire="byName">
    <property name="name" value="zyq">property>
bean>

7.3 ByType自动装配

和ByName类似, 会自动在容器上下文中查找, 和自己对象属性类型相同的bean, 必须保证类型全局唯一

小结:

  • byName的时候, 需要保证所有bean的id唯一, 并且这个bean需要和自动注入的属性的set方法的值一致
  • byType的时候, 需要保证所有bean的class唯一, 并且这个bean需要和自动注入的属性的类型一致

7.4 使用注解自动装配

使用注解须知:

  1. 导入约束, context约束

  2. 配置注解的支持, **(重要)**

    
    <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
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:annotation-config/>
    
    beans>
    

@Autowired可以直接在属性上使用, 也可以在set方法上使用

Autowired使用反射机制, 因此可以不用编写set方法, 前提是自动装配的属性在IoC(Spring)容器中存在, 且符合名字byName

补充:

1. `@Nullable`字段标注了这个注解说明这个字段可以为null
  1. @Autowired(required = false)默认为true, 如果显式定义了属性为false, 说明这个对象可以为null 否则不允许为null
  2. 若@Autowired自动装配环境比较复杂(bean中多个同类对象), 自动装配无法通过一个注解@Autowired完成的时候, 可以使用@Qualifier(value="xxx")来指定

@Resource注解也有自动装配的功能

7.4.1 小结

@Resource@Autowired的异同:

  • 都是用来自动装配的, 都可以放在属性字段上
  • @Autowired默认通过byType方式实现, 而且必须要求这个对象存在
  • @Resource默认通过byName的方式实现, 如果找不到名字, 则通过byType实现, 如果两个方式都找不到就报错

8 使用注解开发

在Spring4之后, 要使用注解开发, 必须要保证aop的包导入了

8.1 bean

@Component放在类上说明类被Spring管理了

8.2 属性如何注入

@Component
public class User {
    public String name;
    @Value("zzz")
    public void setName(String name) {
        this.name = name
	}
}

8.3 衍生注解

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

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

功能都代表将某个类注册到Spring容器中, 装配Bean

8.4 自动装配

- @AutoWired: 通过类型自动装配. 如果Autowired不能通过名字唯一自动装配上属性, 则需要通过@Qualifier(value="xxx")
- @Nullable: 字段标记了这个注解说明这个字段可以为null
- @Resource: 通过名字, 类型自动装配

8.5 作用域

@Scope("prototype")

8.6 小结

xml与注解

  • xml更加万能, 适用于各种场合, 维护简单方便
  • 注解 不是自己的类使用不了, 维护相对复杂

xml与注解最佳实践:

  • xml用来管理bean

  • 注解用来进行属性注入

  • 使用过程中, 只需要注意一个问题: 想让注解生效, 就要开启注解支持

    
    <context:component-scan base-package="com.zyq.pojo">context:component-scan>
    
    <context:annotation-config>context:annotation-config>
    

9.使用Java的方式配置Spring

完全不使用Spring的xml配置

实体类:

@Component
public class User {
    // 属性注入值
    @Value("zyq")
    private String name;
    public String getName() {
        return name;
    }

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

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

配置文件类:

@Configuration // 也会被Spring容器托管, 注册到容器中, 因为这个注解本来就是一个@Component, @Configuration代表这是一个配置类, 相当于beans.xml
@ComponentScan("com.zyq.pojo")
@Import(MyConfig2.class)
public class MyConfig {

    // 注册一个bean, 相当于配置文件xml中的bean标签
    // 方法名相当于bean标签中的id属性
    // 方法的返回值, 相当于bean标签中的class属性
    @Bean
    public User getUser() {
        return new User(); // 就是返回要注入到bean的对象
    }
}

测试类:

public class MyTest {
    public static void main(String[] args) {
        // 如果完全使用类配置类方式, 就只能通过AnnotationConfig上下文来获取容器, 通过配置类的class对象加载
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        User user = (User) context.getBean("getUser");
        System.out.println(user.getName());
    }
}

纯Java的配置方式, 在SpringBoot中随处可见

你可能感兴趣的:(学习笔记)