记录spring学习笔记

1、Spring

1.1、简介

  • spring:译为春天-----给软件行业带来了春天

  • 2202,首次推出了spring框架的雏形,interface21框架!

  • spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2003年3月24日发布了1.0正式版。

  • Rod Johnson,spring framework创始人,著名作者。很难想象Rod Johnson的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业是音乐

  • 使现有的技术更加容易使用,是个大杂烩

  • SSH: Struct2 + Spring + Hibernate

  • SSM:SpringMVC + Springl + Mybatis

需要导入的依赖


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

1.2、优点

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

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

1.3、组成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ioET5T6Q-1592046354066)(C:\Users\d1320\Desktop\1219227-20170930225010356-45057485.gif)]

1.4、拓展

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

因为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及SpringMVC!承上启下的作用

弊端:Spring发展了太久之后,违背了原来的理念!配置十分繁琐,被称为“配置地狱”

2、IOC理论推导

1 . UserDao 接口

public interface UserDao {
     
    void getUser();


}

2.UserDaoImpl实现类

  public void getUser(){
     
        System.out.println("默认获取用户的数据");

    }

3.UserService业务接口

public interface UserService {
     
    void getUser();


    void setUserDao(UserDao userDao);
}

4.UserServiceImlp业务实现类

private UserDao userDao;

    //利用set进行动态实现值的注入

    public void setUserDao(UserDao userDao) {
     
        this.userDao = userDao;
    }

    public void getUser() {
     
        userDao.getUser();
    }

在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求取修改源代码。如果代码量非常大,修改一次的成本价十分昂贵。

我们使用一个Set接口实现

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

IOC本质

控制反转IOC是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法,没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了

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

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

3、hellospring

这个过程就叫控制反转:

控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用spring后,对象是由spring来创建的

反转:程序本身不创建对象,而变成被动的接受对象

依赖注入:就是利用set方法来进行注入的

ioc是一种编程思想,由主动的编程变成被动的接受

可以通过newClassPathXmlApplicationContext去浏览以下底层源码

ok,到了现在,我们彻底不用再程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的ioc就是:对象由spring创建,管理,装配

4、IOC创建对象的方式

1、使用无参构造创建对象,默认!

2、假设我们要使用有参构造创建对象。

​ 1、下标赋值

<bean id="user" class="host.qianlong.pojo.User">

        <constructor-arg index="0" value="breaking">constructor-arg>
    bean>

​ 2、类型


    <bean id="user" class="host.qianlong.pojo.User">
        <constructor-arg type="java.lang.String" value="qianloing"/>
    bean>

​ 3.通过参数名来设置


    <bean id="user" class="host.qianlong.pojo.User">
        <constructor-arg name="name" value="qianlong"/>
    bean>

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

5、spring配置

5.1、别名


<alias name="user" alias-"userNew">alias>

5.2、Bean的配置


5.3、import

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

假设,现在项目有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!

6、依赖注入

6.1、构造器注入

6.2、Set方式注入

  • 依赖注入:set注入
    • 依赖:Bean对象的创建依赖于容器
    • 注入:Bean对象中的所有属性,由容器来注入
<bean id="address" class="host.qianlong.pojo.Address" >
        <property name="address" value="xian"/>
    bean>
    <bean id="student" class="host.qianlong.pojo.Student">

        <property name="name" value="qianlong"/>

        <property name="address"  ref="address"/>

        <property name="books">
            <array>
                <value>三国演义value>
                <value>水浒传value>
                <value>西游记value>
                <value>红楼梦value>
            array>
        property>

        <property name="hobbies">
            <list>
                <value>唱歌value>
                <value>跳舞value>
                <value>写代码value>
            list>
        property>

        <property name="games">
            <set>
                <value>NBAvalue>
                <value>CFvalue>
                <value>LOLvalue>
            set>
        property>

        <property name="card">
            <map>
                <entry key="1" value="qianlong">entry>
                <entry key="2" value="zhangna">entry>
            map>
        property>
        <property name="wife">
            <null/>
        property>

        <property name="info">
            <props>
                <prop key="username">123prop>
                <prop key="password">456prop>
            props>
        property>
    bean>

6.4、

1.单例模式

<bean id="user" class="host.qianlong.pojo.User" scope="singleton"/>

2.原型模式:每次从容器中get的时候,都会产生一个新对象

<bean id="accountService" class="com.someting.DefaultAccountService"/>

3.其余的request,session,application、这些只能再web开发中使用到

7、Bean的自动装配

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

在spring中有三种装配的方式

1.在xml中显示的配置

2.在java中显示配置

3.隐式的自动装配bean

7.1、ByName自动装配

<bean id="person" class="host.qianlong.pojo.Person" autowire="byName">
        <property name="name" value="qianlong"/>
        <property name="dog" ref="dog"/>
        <property name="cat" ref="cat"/>

    bean>

7.3、ByType自动装配

<bean id="person" class="host.qianlong.pojo.Person" autowire="byType">
        <property name="name" value="qianlong"/>
        <property name="dog" ref="dog"/>
        <property name="cat" ref="cat"/>

    bean>

小结:

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

7.4、使用注解实现自动装配

jdk1.5支持的注解,spring2.5就支持注解了

要使用注解须知:

​ 1.导入约束:context约束

​ 2.配置注解的支持:context:annotation-config/


<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

科普

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

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

测试代码

//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
    private String name;
    @Autowired(required = false)
    private Cat cat;
    @Autowired
    private Dog dog;

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value=‘xxx’)去设置@Autowired的使用,指定一个唯一的bean对象注入!

//    @Qualifier(value = "cat2")
    private Cat cat; 

小结:
@Resource和@Autowired的区别:

  • 都是用来自动装配的,都是可以放在属性字段上

  • @Autowired通过ByType的方式实现,而且必须要求这个对象存在

  • @Resource默认通过Byname的方式实现那,如果找不到名字,则通过哟ByType实现,如果连个都找不到的情况下,就会报错!

  • 执行顺序不同:@Autowired通过ByType的方式实现!

8、使用注解开发

1.bean

2.属性如何注入

@Value("tongmeng")
    //相当于
    public String name = "qianlong";

3.衍生的注解

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

  • dao【@Repository】
  • service【@Service】
  • controller【@Controller】

这四个注解功能都是一样的,都是代表某个类注册到spring中,装配bean

4.自动装配置

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

5.作用域

@Component
@Scope("property")
public class User {
     
    @Value("tongmeng")
    //相当于
    public String name = "qianlong";

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

6.小结

xml与注解:

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

xml与注解最佳时间:

  • xml用来管理bean;

  • 注解只负责完成属性的注入:

  • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持

        <context:component-scan basepackage="host.qianlong.pojo"/>
    

9、代理模式

9.1、静态代理

角色分析:

  • 抽象角色:一般会使用接口或者抽象类来解决
  • 真实角色:被代理的角色
  • 代理角色角色:代理真实角色,代理真是角色后,我们一般会做一些附属操作
  • 客户:访问代理对象的人!

代码步骤:

1.接口

public interface Rent{
     
    void rent();
}

2.真实角色

public class Host implements Rent{
     
    public void rent(){
     
        System.out.println("房东要出租房子")
    }
}

3.代理角色

public class Proxy implements Rent{
     
    private Host host;

    public Proxy() {
     
    }

    public Proxy(Host host) {
     
        this.host = host;
    }

    public void aa() {
     
        seeHouse();
        host.aa();
        pact();
        fare();
    }
    //看房
    public void seeHouse(){
     
        System.out.println("中介带你看房子");
    }
    //签合同
    public void pact(){
     
        System.out.println("签租赁合同");
    }
    //收中介费
    public void fare(){
     
        System.out.println("收取服务费");
    }
}

4.客户端访问代理角色

public class Client {
     

    public static void main(String[] args) {
     
        //房东需要租房子
        Host host = new Host();
        //代理,中介帮房东租房子,但实际呢?代理一般慧有一些负数操作
        Proxy proxy = new Proxy(host);

        //你不用找房东,直接找中介租房即可
        proxy.aa();

    }
}

优点:

  • 可以使真是角色的操作更加纯粹!不用去关注一些公共的业务
  • 公共也就交给代理角色!实现了业务的分工
  • 公务业务发生扩展的时候,方便集中管理

缺点:

  • 一个真是角色就会产生一个代理角色,代码量会翻倍-开发效率会变低!

9.2、动态代理

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是我们直接写好的
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
    • 基于接口–JDK动态大力【】
    • 基于类:cglib
    • java字节码实现:javasist

需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序

动态代理的好处:

  • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
  • 公共也就就交给代理角色!实现了业务的分工!
  • 公共业务发生扩展的时候,方便集中管理!
  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可!

10、声明式事务

1、回顾事务

  • 把一组业务当成一个业务来做,要么都成功,要么都失败!
  • 事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎
  • 确保完整性和一致性

事务ACID原则:

  • 原子性
  • 一致性
  • 隔离性
    • 多个业务可能操作同一个资源,防止数据损坏
  • 持久性
    • 事务一旦提交,无论系统发生什么问题,结果都不会再被英雄,被持久化的写到存储器中

2、spring中的事务管理

  • 声明式事务:AOP
  • 编程式事务:需要再代码中进行事务的管理

为什么需要事务?

  • 如果不配置事务,可能存在数据提交不一致的情况
  • 如果我们不在spring中去配置声明式事务,我们就需要再代码中手动配置事务
  • 事务再项目的开发中十分重要,涉及到数据的一致性和完整性问题,不容马虎

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