Spring笔记

1.Spring

1.1简介

下载地址:repo.spring.io 不要管怎么来的,下载最新的就是了,Spring反正是向下兼容的

官方说明文档:Core Technologies (spring.io)

关于导包:spring-webmvc(这是最庞大的那个包)/spring-jdbc

  • SSH: Struct2+Spring+Hibernate
  • SSM: SpringMvc+Spring+Mybatis

1.2优点

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

总结一句话,Spring就是一个轻量级的控制反转(IOC)和面向切面编程的框架

(控制反转:本来是我控制你,现在变成你控制我,主要是在new对象和set对象那一块,作用是用来解耦合,应该是这个意思)

1.3它的组成

主要由七大模块组成

1.4扩展

在Spring官网有这么个介绍,现在的java开发,说白了就是基于spring的开发

  • Spring Boot

    • 一个快速开发的脚手架
    • 基于SpringBoot可以快速的开发单个的微服务
    • 约定大于配置
  • Spring Cloud

    • 它是基于Spring Boot实现的

学SpringBoot需要掌握Spring和SpringMVC,如果你前面不了解,那么你听后面整个都是蒙的,没有啥效果,这我是深有体会.Spring非常重要

2.Spring-IOC

2.1理论推导

​ 就是说在以前,我们需要有dao+dao层的Mapper+service+service的impl,当有新的需求增加的时候,就要去修改原码,并且原码改的是new xxximpl();目的是为了拿到这个实现类的对象,此时是程序控制对象;当我们用setxxx方法的时候,就是对象控制程序,因为参数传的就是对象,很灵活,我们只需改变参数就可以了;总结:以前是程序主动创建对象,现在是根据用户传进来的参数是谁,我们再决定为谁创建对象,被动的接收对象,这就是控制反转,主动权由程序变到用户手上

在java中,传参比直接强改代码要好

3.HelloSpring

​ spring也依赖于配置,简称"配置地狱";xml文件模板在核心技术 (spring.io)
里面的配置元数据那一块,就是用配置文件来创建对象,想初始化也可以初始化

​ spring默认调用的是无参的构造器,它里面的标签是,所以它是通过set赋值的,里面的ref是给setxxx对象使用的,ref="实现类",因为setxxx里面要传参,所以传的就是实现类

总结:基本数据类型用value,自己的对象什么的用ref

​ 若想用有参构造器,在说明文档的Dependencies->dependency Injection->constructor-baseed DI,提供了模板

<!--    调用无参构造器,id可以说是这个bean标签的唯一标识符,也可以说是这个对象的名字,class就是全限定名-->
    <bean id="user" class="com.kuang.pojo.User">
        <property name="name" value="tom"></property>
        <property name="pwd" value="123"></property>
    </bean>

<!--    有参-->
    <bean id="user2" class="com.kuang.pojo.User">
        <constructor-arg index="0" value="jack"/>
        <constructor-arg index="1" value="42"/>
    </bean>
<!--    有参-->
    <bean id="user3" class="com.kuang.pojo.User">
        <constructor-arg name="name" value="jack"/>
        <constructor-arg name="pwd" value="42"/>
    </bean>

必要代码:

ApplicationContext context = new ClassPathXmlApplicationContext("user.xml");//实例化Spring的容器,也可以说获取spring的上下文对象
User user =(User) context.getBean("user");//从容器中拿对象

​ 那么这里怎么就体现了控制反转(Incersion of Control,缩写为IOC)了呢?
​ 对象不由程序创建,由spring创建;程序变成被动的接收对象

依赖注入(Dependency Injection,简称DI):就是利用set方法来进行注入

现在我们就不用去创建对象了,就在xml文件中配置,交给spring打理

对象的创建出现在创建spring容器的时候,就是读取xml文件的时候,也就是获得spring上下文的那个方法

spring容器中的对象只有一份,当你getBean的时候,只要里面的参数相同,那就是同一个对象

4.Spring配置

4.1别名

<alias name="user2" alias="asd"></alias>//就是将你的对象名称换个名字,不过一般不这样取别名,如下,可以取多个别名
 <bean id="user2" class="com.kuang.pojo.User" name="u3,u4"></bean>

4.2import

​ 一般用于团队开发,将多个配置文件导入,相当于导包;比如在一个总配置文件中导入这些个包之后,只需要读这个总配置文件就可以使用这三个了

	<import resource="admin.xml"></import>
    <import resource="user.xml"></import>
    <import resource="beans.xml"></import>

5.依赖注入

  • 分为构造器注入/Set方式注入/扩展方式注入(c/p)
    • 依赖: bean对象的创建依赖于容器
    • 注入: bean对象中的所有属性,有容器来注入

5.1普通注入:

<?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">

    <!-- services -->
    <bean id="address" class="com.kuang.pojo.Address">
        <property name="street" value="解放西"></property>
    </bean>

    <bean id="student" class="com.kuang.pojo.Student">
        <property name="name" value="tom"></property>
        <property name="address" ref="address"></property>
<!--        数组-->
        <property name="books">
            <array>
                <value>红楼梦</value>
                <value>水浒传</value>
                <value>西游记</value>
                <value>三国演义</value>
            </array>
        </property>
<!--        map集合-->
        <property name="card">
            <map>
                <entry key="身份证" value="123"></entry>
                <entry key="银行卡" value="123456"></entry>
            </map>
        </property>
<!--        list集合-->
        <property name="hobby">
            <list>
                <value>打篮球</value>
                <value>吃饭</value>
                <value>看电影</value>
                <value>约会</value>
            </list>
        </property>
<!--        不设置值得时候-->
        <property name="girlfriend">
            <null></null>
        </property>
<!--        Set集合-->
        <property name="games">
            <set>
                <value>cs'go</value>
                <value>cf</value>
            </set>
        </property>
<!--        Properties类型,就那个配置文件类型-->
        <property name="info">
            <props>
                <prop key="学号">1900130305</prop>
                <prop key="姓名">大龙</prop>
            </props>
        </property>
    </bean>

    <!-- more bean definitions for services go here -->

</beans>

5.2c命名和p命名空间注入

​ 这需要导入一些约束

p注入就是加了这样一行,p就是property的意思
xmlns:p="http://www.springframework.org/schema/p"

<bean id="product" class="com.kuang.pojo.Product" p:num="12" p:price="10.0"></bean>//可以直接注入属性的值

c注入也是加了这样一行,c就是构造器的意思
xmlns:c="http://www.springframework.org/schema/c"

<bean id="product2" class="com.kuang.pojo.Product" c:_0="123" c:_1="123"></bean>

(在Spring中,创建对象默认调用的是无参构造器,所以必须提供,p标签可以没有有参构造器,c标签必须要有有参构造器)

总结一点:无参和有参都必须提供

6.Bean的作用域(scope属性)

6.1单例模式Singleton(Spring默认机制)

​ 始终只有一个对象

6.2原型模式prototype

​ 就跟传统的一样,每创建一个对象就new一个对象

7.Bean的自动装配

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

传统的:

<!--    我们的所有装配都在这里显示的定义了-->
    <bean id="dog" class="com.kuang.pojo.Dog"></bean>

    <bean id="car" class="com.kuang.pojo.Car"></bean>

    <bean id="person" class="com.kuang.pojo.Person">
        <property name="dog" ref="dog"></property>
        <property name="car" ref="car"></property>
    </bean>

根据名字自动装配 (根据名字在xml文件中找,但是这个名字的属性的名字,若dog222...就不可以了):

<!--    自动装配-->
    <bean id="dog" class="com.kuang.pojo.Dog"></bean>
    <bean id="car" class="com.kuang.pojo.Car"></bean>
    <bean id="person" class="com.kuang.pojo.Person" autowire="byName"></bean>

根据类型自动装配: byType,这事就可以随意写名字了,甚至省去id不写也可以,因为是根据类型查找的,但是必须保证这个类型只有一个,不然就不知道找哪个了,

使用注解实现自动装配@Autowired

版本要求:至少jdk1.5,spring2.5

准备条件: 约束和一个标签:

xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:annotation-config/>//这叫注解的支持,有了这个才能使用注解

模板如下:

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:annotation-config/>
    

</beans>

源代码如下,就是说person里面有dog和car对象,你只需要在Person类里面的Dog变量和Car变量上面加@Autowired,注意,这两个都要加,这就实现了自动装配,你就能够拿到这两个对象了

自动装配@Autowired是根据类型匹配的

<bean id="car" class="com.kuang.pojo.Car"></bean>
<bean id="dog" class="com.kuang.pojo.Dog"></bean>
<bean id="person" class="com.kuang.pojo.Person"></bean>

注解是通过反射来实现的,可以不用set方法,也能拿到对象,有时间去深究一下

扩展

@Nullable 这个参数可以为空

public Person(@Nullable String name) {
    this.name = name;
}

这是既然是一个注解,那么就可以传参,下面false意味着这个对象可以为空

@Autowired(required = false)
    private Car car;
@Qualifier(value = "222")//代表增加一个别名,id取222的时候也可以拿到它,一般在@Autowired环境比较复杂的时候配合使用

此外,使用java自带的注解@Resource也可以自动装配
这个比@Autowired强大,它既可以根据类型匹配,也可以根据名字匹配,默认是名字

8.使用注解开发

9.Spring的AOP

它是oop的延续

特点:

  • 能在不修改源代码的情况下,对功能进行增强优化
  • 能把相同的功能抽离出来
  • 解耦合。不把AOP的代码和其它代码写在一起,专门用一个配置文件来告诉程序,我要在运行时把这个AOP的代码加到某个代码中

AOP的底层实现

它是通过 Spring 提供的动态代理技术去动态的生成代理对象。猫腻就在这里,这个代理对象在调用目标对象方法的同时,加上一些自己的代码,从而实现功能的增强

常用的动态代理技术:

  • JDK 代理:基于接口的动态代理技术
  • cglib 代理:基于父类的动态代理技术(类似于继承,但底层不是继承实现的)
posted @ 2021-12-26 12:07  朱在春  阅读(30)  评论(0编辑  收藏  举报