Spring整体学习笔记-IoC依赖注入-AOP代理-整合Spring-Mybatis

Spring

简介

行业春天

解决企业级开发的复杂性,使现有的技术更容易使用,本身是个大杂烩,整合了现有的技术框架

不要重复造轮子

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

官网:https://spring.io/projects/spring-framework#overiew

官方下载地址:https://repo.spring.io/release/org/springframework/spring/
可以下载到所有的版本

GitHub:https://github.com/spring-projects/spring-framework

SpringWebMVC依赖文本

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.7.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.7.RELEASE</version>
</dependency>

两个包:

  • springWebMVC
  • springJDBC

Spring优点

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

Spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架

Spring组成

spring组成的七大模块

image-20200821075431512

  • 核心容器(SpringCore)
    • 核心容器提供Spring框架的基本功能。spring以bean的方式组织和管理Java应用的各个组件及其关系,spring使用BeanFactory来产生和管理Bean,是工厂模式的实现,BeanFactory使用控制反转(IoC)模式将应用的配置和依赖性规范与实际的应用程序代码分开
  • 应用上下文(Spring Context)
    • Spring上下文是一个配置文件,向spring提供上下文信息,spring上下文包括企业服务、、、、
  • Spring面向切面编程(Spring AOP)
    • AOP(Aspect Oriented Programming)
    • 通过配置管理特性,SpringAOP模块直接将面向方法的编程功能集成在了Spring框架中,Spring管理的任何对象都支持AOP,SpringAOP模块基于Spring的应用程序中的对象提供了事务管理服务,通过使用SpringAOP,不用依赖EJB组件,就可以将声明性事务管理集成在应用程序中
  • JDBC和DAO模块(Spring DAO)
    • Dao(Data Access Object)
    • JDBC、DAO的抽象层,提供了有意义的异常层次结构实现,可用该结构来管理异常处理,和不同数据库提供商抛出的错误信息,异常层次结构简化了错误处理,并且极大的降低了需要编写的代码数量,比如打开和关闭链接。
  • 对象实体映射(Spring ORM)
    • ORM(Object Relational Mapping)
    • Spring插入了若干个ORM框架,提供了ORM对象的关系工具,其中包括Hibernate,JDO和IBatisSQL Map等,所有这些都遵从Spring的通用事务和DAO异常层次结构
  • Web模块(Spring Web)
    • web上下文模块建立应用程序上下文模块之上,基于web的应用程序提供了上下文,所以spring框架支持与Struts集成,web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作
  • MVC模块(SpringWebMVC)
    • MVC(Model View Controller)
    • MVC框架是一个全功能的构建Web应用程序的MVC实现,通过策略接口,MVC框架编程高度可配置的,MVC容纳了大量视图技术,其中包括JSP,POI等,模型由JavaBean来构成,存放于m当中,而视图是一个接口,负责实现模型,控制器表示逻辑代码,由c的事情。spring框架的功能可以用在任何J2EE服务器当中,大多数功能也适用于不受管理的环境,spring的核心要点就是支持不绑定到特定J2EE服务的可重用业务和数据的访问对象,毫无疑问这样的对象可以在不同的J2EE环境,独立应用程序和测试环境之间重用

Spring介绍

image-20200820153254168

  • SpringBoot
    • 快速开发脚手架
    • 可以快速开发单个微服务,把一个功能单独提取出来就是一个微服务
    • 约定大于配置,主要学习他的配置
    • 学习SpringBoot的前提是要掌握Spring和SpringMVC
  • SpringCloud
    • SpringCloud基于SpringBoot实现的

IOC理论推导

之前使用的流程:

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

在之前的业务中,用户的需求会影响到我们原来的代码,需要根据用户需求去修改源代码,如果程序代码量巨大,修改一次的成本十分昂贵

使用set接口来实现也是一种动态实现 值的注入

  • 之前,程序是主动创建对象,控制权在程序员手上
  • 使用了set注入后,程序不再具有主动性,而是变成了被动的接受对象

这种思想,本质上解决了问题,程序员不用再去管理对象的创建,系统的耦合性大大的降低,可以更加专注的在业务的实现上,这是IOC的原型

以前的架构

image-20200821105321848

现在的架构

image-20200821105416863

IOC本质

  • 是一种设计思想,DI(依赖注入)是实现IOC的一种方法,原先创建对象由程序自己控制,控制反转后,创建转移给第三方,获得依赖对象的方式反转了

image-20200821105756534

  • IoC是Spring框架的核心内容
    • 可以使用XML配置
    • 可以使用注解
    • 不配置也行,自动装填
  • 控制反转时一种通过描述(XML或注解)并通过第三方生产或获取特定对象的方式,在Spring中实现控制反转的时IoC容器,其实现方法是依赖注入(Dependency Injection ,DI)

HelloSpring

制作一个简单演示,如何将new对象交给第三方来做,用户可以通过修改xml文件来实现IoC操作

  • 导入包
  • 配置类加载路径应用上下文xml文件
  • 编写JavaBean
  • 测试,通过上下文获取bean来new对象
  1. 导入包

    1. <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.2.7.RELEASE</version>
      </dependency>
      
    2. 主要是这个,其他随意

  2. 配置类加载路径应用上下文xml文件

    1. 文件名,spring官方文档是有说的,官方推荐起名为ApplicationContext

    2. 配置xml元数据

    3. 官方有给初始模板

    4. <?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 id="..." class="...">  
              <!-- collaborators and configuration for this bean go here -->
          </bean>
      
          <bean id="..." class="...">
              <!-- collaborators and configuration for this bean go here -->
          </bean>
      
          <!-- more bean definitions go here -->
      
      </beans>
      
  3. 编写Bean

    1. @Data
      public class Hello {
             
          private String str;
      }
      
    2. 写好bean之后要写入ApplicationContext

    3. <?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 id="Hello" class="com.haoyun.POJO.Hello">
              <property name="str" value="haoyun"/>
          </bean>
      </beans>
      
    4. 设置一个id,对里面的成员变量可以进行设置

    5. 设置好的Bean会有一个小标志

    6. image-20200821134856756

  4. 测试

    1. public class MyTest {
             
          @Test
          public void BeanTest(){
             
              ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("Beans.xml");
              Hello hello = (Hello) classPathXmlApplicationContext.getBean("Hello");
              System.out.println(hello.toString());
          }
      }
      
    2. 填应用上下文的位置,产生出了ApplicationContext对象就能获取里面的Bean了,产生Bean对象

IOC创建对象的方式

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

  2. 使用有参构造,通过构造器创建

    1. @Data
      public class Hello {
             
          private String name;
          public Hello(String name){
             
      
          }
      }
      
    2. 添加了一个有参构造函数

    3. <bean id="Hello" class="com.haoyun.POJO.Hello">
          <property name="name" value="sdafsdf"/>
      </bean>
      
    4. 配置没变

    5. 爆出错误提示

    6. image-20200821160505519

    7. 没有找到默认的构造函数

    8. 这时就要看官方文档了,这里找到一篇中文的官方文档

    9. https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/core.html#beans

    10. image-20200821161323423

    11. 里面讲到一个有参构造器的依赖注入问题

依赖注入的两种变体

DI依赖注入存在两种主要变体:ConstructorSetter 的两种依赖注入

Constructor

  1. image-20200821162141834

  2. <beans>
        <bean id="thingOne" class="x.y.ThingOne">
            <constructor-arg ref="thingTwo"/>
            <constructor-arg ref="thingThree"/>
        </bean>
    
        <bean id="thingTwo" class="x.y.ThingTwo"/>
    
        <bean id="thingThree" class="x.y.ThingThree"/>
    </beans>
    
  3. 有参构造函数以这种形式注册,然后包括了下列三种形式

  4. <bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg type="int" value="7500000"/>
        <constructor-arg type="java.lang.String" value="42"/>
    </bean>
    
  5. 如果参数是简单类型就添加type和value,(根据类型的)

  6. <bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg index="0" value="7500000"/>
        <constructor-arg index="1" value="42"/>
    </bean>
    
  7. 还可以使用索引,从0开始(根据索引的)

  8. <bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg name="years" value="7500000"/>
        <constructor-arg name="ultimateAnswer" value="42"/>
    </bean>
    
  9. 消除歧义,加入name,直接规定argument 的name(根据参数名的)

Setter

调用no-argument构造函数,或static工厂方法来实例化Bean

ApplicationContext管理Beans的Constructor和setter的DI,

可以使用properties的格式,但是一般使用XML,或者注解@Controller等

Constructor和Setter是可以混合使用的

Setter注入应该要有合理的默认值,否则,应该添加not-null检查

  • 可以由xml、JavaCode、annotations指定
  • 每个property(属性)或构造函数参数都要设置value的实际定义,或是容器的另一个引用,如参数不是基本类型,就要找到容器中对应bean的reference(引用)

循环依赖

  • classA通过构造函数实注入实现classB,classB又通过构造函数注入实现classA,这种配置bean的相互注入,会被SpringIoC判定为循环reference,并抛出BeanCurrentlyInCreationException
  • 要求beanA和beanB之间必须有一个被完全初始化,再注入另一个,典型的先有鸡还是先有蛋的问题

Setter-Based example

  1. public class ExampleBean {
         
    
        private AnotherBean beanOne;
    
        private YetAnotherBean beanTwo;
    
        private int i;
    
        public void setBeanOne(AnotherBean beanOne) {
         
            this.beanOne = beanOne;
        }
    
        public void setBeanTwo(YetAnotherBean beanTwo) {
         
            this.beanTwo = beanTwo;
        }
    
        public void setIntegerProperty(int i) {
         
            this.i = i;
        }
    }
    
  2. <bean id="exampleBean" class="examples.ExampleBean">
        <!-- setter injection using the nested ref element -->
        <property name="beanOne">
            <ref bean="anotherExampleBean"/>
        </property>
    
        <!-- setter injection using the neater ref attribute -->
        <property name="beanTwo" ref="yetAnotherBean"/>
        <property name="integerProperty" value="1"/>
    </bean>
    
    <bean id="anotherExampleBean" class="examples.AnotherBean"/>
    <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
    
  3. 和constructor-based的差距真不大,只是多了一点环节而已

  4. <bean id="exampleBean" class="examples.ExampleBean">
        <!-- constructor injection using the nested ref element -->
        <constructor-arg>
            <ref bean="anotherExampleBean"/>
        </constructor-arg>
    
        <!-- constructor injection using the neater ref attribute -->
        <constructor-arg ref="yetAnotherBean"/>
    
        <constructor-arg type="int" value="1"/>
    </bean>
    
    <bean id="anotherExampleBean" class="examples.AnotherBean"/>
    <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
    
  5. wc,东西太多了,根本翻不完,形式太多,表达的又是相近的意思

最简单就直接

<bean id="Hello" class="com.haoyun.POJO.Hello">
	<constructor-arg name="name" value="haoyun"/>
</bean>

真是没事找事

别名alias

<bean id="Hello" class="com.haoyun.POJO.Hello">
    <constructor-arg name="name" value="haoyun"/>
</bean>
<alias name="Hello" alias="safsdf"/>

原来的名字也能用,别名也能用

这个又是没用的,直接再bean标签使用name也能起别名,里面的内容,用逗号或分号或空格都能起别名

<bean id="Hello" class="com.haoyun.POJO.Hello" name="hello afsdfaf,sadfasdf">

import配置文件

之前官网说一个正规的beans命名为applicationContext.xml,这是一个总的配置文件,项目中可以有多个配置文件,这样的好处是,可以由多个人编写,最后汇总,汇总到主配置文件applicationContext.xml

ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml","Beans.xml");

创建ApplicationContext实例的时候可以选用多个配置文件

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值