spring框架讲解

一 简介 

  • 什么是Spring:轻量级的 DI / IoC 和 AOP 容器的开源框架

  • 有啥好处:

    • 管理创建和组装对象之间的依赖关系 使用前:手工创建

  • 面向切面编程(AOP)可以解耦核心业务和边缘业务的关系

    场景:用户调用下单购买视频接口,需要判断登录,拦截器是AOP思想的一种实现

    使用前:代码写逻辑,每次下单都调用方法判断,多个方法需要判断登录则都需要 登录方法判断

    使用后:根据一定的方法或者路径规则进行判断是否要调用,降低代码耦合度

  • 包含java大型项目里面常见解决方案 web层、业务层、数据访问层等

  • 极其便利的整合其他主流技术栈,比如redis、mq、mybatis、jpa

  • 社区庞大和活跃,在微服务、大数据、云计算都有对应的组件

二 使用 IDEA + Maven + Spring5创建项目

  • 创建项目

    • maven
  • 添加依赖
     

      <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.2.5.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>5.2.5.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>5.2.5.RELEASE</version>
            </dependency>

    添加配置文件applicationContext.xml

  • 添加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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    
        <bean name="video" class="net.xdclass.sp.domain.Video" scope="prototype">
                <property name="name" value="tom"/>
                <property name="id" value="23"/>
        </bean>
    
    </beans>

三 applicationContext.xml配置文件

        bean标签 id属性:指定Bean的名称,在Bean被别的类依赖时使用

        name属性:用于指定Bean的别名,如果没有id,也可以用name

        class属性:用于指定Bean的来源,要创建的Bean的class类,需要全限定名

四 spring的IOC设计思想

  • 什么是IOC Inverse of Control(控制反转)是一种设计思想 将原本在程序中手动创建对象的流程,交由Spring框架来管理 核心:把创建对象的控制权反转给Spring框架,对象的生命周期由Spring统一管理

    把spring ioc 当成一个容器,里面存储管理的对象称为Bean,类实例

  • 案例实操 配置文件里面定义一个bean,通过代码去获取
     

     <bean  name="video" class="net.xdclass.sp.domain.Video">
    
            <property name="id" value="9"/>
            <property name="title" value="Spring 5.X课程" />
    
    </bean>
    
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    
    Video  video = (Video)applicationContext.getBean("video");
    
    System.out.println(video.getTitle());

五 讲解spring的依赖注入讲解

  • 什么是DI Dependency Injection ,依赖注入

    IOC容器在运行期间,动态地将对象某种依赖关系注入到对象之中,比如视频订单对象,依赖用视频对象
     

    <bean id="video" class="net.xdclass.sp.domain.Video">
    
            <property name="id" value="9"/>
            <property name="title" value="Spring 5.X课程" />
    
        </bean>
    
        <bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" >
            <property name="id" value="8" />
            <property name="outTradeNo" value="23432fnfwedwefqwef2"/>
            <property name="video" ref="video"/>
        </bean>
    
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Video  video = (Video)context.getBean("video");
            System.out.println(video.getTitle());
    
    
            VideoOrder videoOrder = (VideoOrder) context.getBean("videoOrder");
            System.out.println(videoOrder.getOutTradeNo());
            System.out.println(videoOrder.getVideo().getTitle());

 六 spring的bean 属性scope作用域
        

    scope属性

  • singleton:单例, 默认值,调用getBean方法返回是同一个对象,实例会被缓存起来,效率比较高 当一个bean被标识为singleton时候,spring的IOC容器中只会存在一个该bean

<!--<bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton"> -->
<bean id="video" class="net.xdclass.sp.domain.Video" scope="prototype">

        <property name="id" value="9"/>
        <property name="title" value="Spring 5.X课程" />

</bean>
  • prototype: 多例,调用getBean方法创建不同的对象,会频繁的创建和销毁对象造成很大的开销

  • 其他少用 (作用域 只在 WebApplicationContext)

    • request :每个Http请求都会创建一个新的bean
    • session: 每个Http Session请求都会创建一个新的bean
    • global session(基本不用)
private static  void testScope(ApplicationContext context){
        Video  video1 = (Video)context.getBean("video");

        Video  video2 = (Video)context.getBean("video");

        //靠匹配内存地址,== 是匹配内存地址
        System.out.println( video1 == video2 );

  }

七 Spring5.X常见的注入方式
 

  • 使用set方法注入
    <bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton">
    
            <property name="id" value="9"/>
            <property name="title" value="Spring 5.X课程" />
    
    </bean>
  • 使用带参的构造函数注入
     <bean id="video" class="net.xdclass.sp.domain.Video" >
    
            <constructor-arg name="title" value="面试专题课程第一季"></constructor-arg>
    
        </bean>
  • POJO类型注入(property 没有使用value属性,而是使用了ref属性)
     <bean id="video" class="net.xdclass.sp.domain.Video" >
    
            <constructor-arg name="title" value="面试专题课程第一季"></constructor-arg>
    
        </bean>
    
    
        <bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" >
            <property name="id" value="8" />
            <property name="outTradeNo" value="23432fnfwedwefqwef2"/>
            <property name="video" ref="video"/>
        </bean>
  • 注意: 类的构造函数重写的时候,一定要保留空构造函数!!!

八 List-Map类型的注入
 

<bean id="video" class="net.xdclass.sp.domain.Video" >

        <!--list类型注入-->
        <property name="chapterList">
            <list>
                <value>第一章SpringBoot</value>
                <value>第二章Mybatis</value>
                <value>第三章Spring</value>
            </list>
        </property>

        <property name="videoMap">
            <map>
                <entry key="1" value="SpringCloud课程"></entry>
                <entry key="2" value="面试课程"></entry>
                <entry key="3" value="javaweb课程"></entry>
            </map>
        </property>
</bean>



public class Video {

    private int id;

    private String title;


    private List<String> chapterList;


    private Map<Integer,String> videoMap;

//省略set get方法
}

九 spring里面bean的依赖和继承

  • bean继承:两个类之间大多数的属性都相同,避免重复配置,通过bean标签的parent属性重用已有的Bean元素的配置信息 继承指的是配置信息的复用,和Java类的继承没有关系
    <bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton">
    
            <property name="id" value="9"/>
            <property name="title" value="Spring 5.X课程" />
    
    </bean>
    
    
    <bean id="video2" class="net.xdclass.sp.domain.Video2" scope="singleton" parent="video">
    
            <property name="summary" value="这个是summary"></property>
    
    </bean>
  • 属性依赖: 如果类A是作为类B的属性, 想要类A比类B先实例化,设置两个Bean的依赖关系
    <bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton">
    
            <property name="id" value="9"/>
            <property name="title" value="Spring 5.X课程" />
    
    </bean>
    
    <!--设置两个bean的关系,video要先于videoOrder实例化-->
    
    <bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" depends-on="video">
            <property name="id" value="8" />
            <property name="outTradeNo" value="23432fnfwedwefqwef2"/>
            <property name="video" ref="video"/>
    </bean>

    十 spring里面bean的生命周期里面的init和destroy方法
     

    <bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton" init-method="init" destroy-method="destroy">
    
            <property name="id" value="9"/>
            <property name="title" value="Spring 5.X课程" />
    
    </bean>
    
    
    
    public static void main(String [] args){
    
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    
    
    
      ((ClassPathXmlApplicationContext) context).registerShutdownHook();
    
     }

十一 Spring的BeanPostProcessor使用 

  • 什么是BeanPostProcessor

    • 是Spring IOC容器给我们提供的一个扩展接口
    • 在调用初始化方法前后对 Bean 进行额外加工,ApplicationContext 会自动扫描实现了BeanPostProcessor的 bean,并注册这些 bean 为后置处理器
    • 是Bean的统一前置后置处理而不是基于某一个bean
  • 执行顺序
    Spring IOC容器实例化Bean
    调用BeanPostProcessor的postProcessBeforeInitialization方法
    调用bean实例的初始化方法
    调用BeanPostProcessor的postProcessAfterInitialization方法
  • 注意:接口重写的两个方法不能返回null,如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bean实例对象

    public class CustomBeanPostProcessor implements BeanPostProcessor,Ordered {
    
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    
            System.out.println("CustomBeanPostProcessor1 postProcessBeforeInitialization beanName="+beanName);
    
            return bean;
        }
    
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("CustomBeanPostProcessor1 postProcessAfterInitialization beanName="+beanName);
            return bean;
        }
    
    
        public int getOrder() {
            return 1;
        }
    }
    
  • 可以注册多个BeanPostProcessor顺序

    • 在Spring机制中可以指定后置处理器调用顺序,通过BeanPostProcessor接口实现类实现Ordered接口getOrder方法,该方法返回整数,默认值为 0优先级最高,值越大优先级越低

十二 Spring的Bean的自动装配属性autowire

  • 属性注入

    • 前面学过属性注入,set方法、构造函数等,属于手工注入
    • 有没办法实现自动装配注入?
  • Spring自动注入

    • 使用元素的 autowire 属性为一个 bean 定义指定自动装配模式

    • autowire设置值

      • no:没开启

      • byName: 根据bean的id名称,注入到对应的属性里面

      • byType:根据bean需要注入的类型,注入到对应的属性里面

        • 如果按照类型注入,存在2个以上bean的话会抛异常
        • expected single matching bean but found 2
      • constructor: 通过构造函数注入,需要这个类型的构造函数

    • <!--<bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" autowire="byName">-->
      <!--<bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" autowire="byType">-->
          <bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" autowire="constructor">
      
              <property name="id" value="8" />
              <property name="outTradeNo" value="23432fnfwedwefqwef2"/>
          </bean>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值