Spring框架简介

本文详细介绍了Spring框架的核心概念,包括Spring的起源、组成、插件安装,以及IoC(控制反转)和DI(依赖注入)原理。深入探讨了Spring的IoC容器、bean的配置、作用域以及依赖注入的不同方式。同时,讲解了Spring的自动装配、注解开发、JavaConfig配置、代理模式(静态与动态)、AOP(面向切面编程)的概念、组成部分、实现方式、切入点表达式和通知类型。最后,提到了Spring与Mybatis的整合以及事务管理,包括声明式和注解式事务。
摘要由CSDN通过智能技术生成

Spring

1. Spring简介

1.1 什么是Spring

  • Spring框架是一个开源、非入侵式、轻量级应用程序框架, 由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。

  • Spring框架主要由七部分组成,分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。

  • 设计理念:解决企业级开发的复杂性。拥有强大的向后兼容性。

  • 2002年,首次推出了Spring框架的雏形:interface21.

  • Spring框架以interface21为基础,不断丰富于2004年3月24日发布了1.0正式版本。

  • Rod Johnson, Spring Framework创始人,著名作者。 在尼大学不仅获得了计算机学位,同时还获得了音乐学位。更令人吃惊的是在回到软件开发领域之前,他还获得了音乐学的博士学位。很难想象Rod Johnson的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。

  • SSM:SpringMVC + Spring + Mybatis

1.2 如何获取Spring

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

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

1.3 Spring组成

  • Spring Core:是框架的最基础部分,并提供依赖注入(Dependency Injection)管理Bean容器功能。

  • Spring Context:构建于Core包上,提供了一种框架式访问对象的方式,有些像JNDI注册。Context封装包继承了beans包的功能,还增加了国际化(I18N),事件传播,资源装载,以及透明创建上下文,例如通过servlet容器。

  • Spring DAO:提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。并且,JDBC封装包还提供了一种比编程性更好的声明性事务管理方法,不仅仅是实现了特定接口,而且对所有的POJOs都适用。

  • Spring ORM:流行的“关系/对象”映射APIs提供了集成层,包括JDO,hibernate和iBatis。通过ORM包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,如前边提到的简单声明性事务管理。

  • Spring AOP:提供了符合AOP Alliance规范的面向方面的编程实现,例如方法拦截器(method-interceptors)和切点(pointcuts),从逻辑上讲,从而减弱代码的功能耦合,清晰的被分离开。

  • Spring Web:提供了基本的面向Web的综合特性,例如多方文件上传,利用Servlet listeners进行IoC容器初始化和针对Web的applicationcontext。当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。

  • Spring Web MVC:提供了面向Web应用的Model-View-Controller实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型,在领域模型代码和web form之间。并且,还可以借助Spring框架的其他特性。

1.4 Spring插件的安装

1.4.1 下载插件包

先确定eclipse的版本号,下载对应的插件包。

1.4.2 安装插件包
  1. Help --> install new software

  2. window --> preferences 下面能看到Spring模块说明安装成功。

2. IOC

2.1 IOC概述

​ IOC( Inverse of Control )翻译为控制反转。不是什么技术,而是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。

2.2 举个栗子

​ 控制反转显然是一个抽象的概念,我们举一个鲜明的例子来说明。

​ 在现实生活中,人们要用到一样东西的时候,第一反应就是去找到这件东西,比如想喝新鲜橙汁,在没有饮品店的日子里,最直观的做法就是:买果汁机、买橙子,然后准备开水。值得注意的是:这些都是你自己“主动”创造的过程,也就是说一杯橙汁需要你自己创造。

​ 然而到了今时今日,由于饮品店的盛行,当我们想喝橙汁时,第一想法就转换成了找到饮品店的联系方式,通过电话等渠道描述你的需要、地址、联系方式等,下订单等待,过一会儿就会有人送来橙汁了。

​ 请注意你并没有“主动”去创造橙汁,橙汁是由饮品店创造的,而不是你,然而也完全达到了你的要求,甚至比你创造的要好上那么一些。

​ 这就是一种控制反转的理念,上述的例子已经很好的说明了问题,我们再来描述一下控制反转的概念:控制反转是一种通过描述(在 Java 中可以是 XML 或者注解)并通过第三方(Spring)去产生或获取特定对象的方式。

2.3 Spring IoC容器

Spring 会提供 IoC 容器来管理和容纳我们所开发的各种各样的 Bean,并且我们可以从中获取各种发布在 Spring IoC 容器里的 Bean,并且通过描述可以得到它。

2.4 优点

​ 解耦!解耦!!解耦!!!解耦!!!!

案例参考:Spring-ioc-demo

3. 第一个Spring程序

3.1 引入依赖

需要什么模块加什么模块

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.4.RELEASE</version>
</dependency>

3.2 定义Java类

public class Student {
   
	
	private String name  ;
	
	public String getName() {
   
		return name;
	}

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

	public void study(){
   
		System.out.println("好好学习,天天向上。");
	}
    
    	@Override
	public String toString() {
   
		return "Student [name=" + name + "]";
	}
	 
}

3.3 配置bean

resources目录下新建配置文件applicationContext.xml,内容如下:

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

	
	<bean id="student" class="com.blb.spring.Student">
		<property name="name" value="seven" />
	</bean>

</beans>

3.4 测试

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getName());
student.study();

思考:

  1. 步骤3.2中定义的Student类中可以定义一个带参构造方法吗?为什么?
  2. 自己写个IOC容器?

4. IOC创建对象的方式

  1. 通过无参构造方法(默认),属性通过setter方法(默认)

  2. 有参构造方法

  • 第1种:下标匹配

    	<bean id="student" class="com.blb.spring.Student">
    	<!--  index表示下标,0:第一个参数。value要传入的参数值    -->
    		<constructor-arg index="0" value="seven"></constructor-arg>
    	</bean>
    
  • 第2种:类型匹配

    <bean id="student" class="com.blb.spring.Student">
    	<!--  type表示根据参数类型来查找参数;value要传入的参数值    -->
    <constructor-arg  type="java.lang.String" value="seven"></constructor-arg>
    </bean>
    

    如果参数列表有多个相同类型的话就无法匹配上了,故不推荐此种方式。

  • 第3种:参数名匹配

    <bean id="student" class="com.blb.spring.Student">
    	<!--  name表示根据参数名称来查找参数;value要传入的参数值    -->
        <constructor-arg  name="name"   value="seven"></constructor-arg>
    </bean>
    

总结:

  • applicationContext.xml中定义的bean是在容器启动的时候就已经实例化好里面的对象了,而不是在

context.getBean用的时候才实例化。

  • 容器默认实例化是一个对象,多次context.getBean获取到的对象都是同一个。

5. Spring配置

5.1 别名

  • 我们可以给实例添加别名,在getBean的时候也可以用别名来获取了.
	<alias name="student"  alias="user"  />

5.2 bean的配置

	<bean id="student" class="com.blb.spring.Student"  name="s1,s2 s3;s4" >
		<constructor-arg  name="name"   value="seven"></constructor-arg>
	</bean>
  • id:bean的唯一标识符,相当于我们取的对象名
  • class:bean对应的全限定名: 包名+类名
  • name:也是别名,而且可以取多个别名,多个别名之间可以用空格、逗号、封号隔开。

5.3 import

import用于协同开发中,将多个配置文件合并到一个中。比如applicationContext.xml中

	<import resource="bean1.xml"/>
	<import resource="bean2.xml"/>
  • 表示把bean1.xml跟bean2.xml中的配置都引入到当前文件中。

  • 当有冲突的时候按照顺序后面覆盖前面的原则。

5.4 scope(作用域)

5.4.1 单例模式(默认)
  • 单例模式下容器只会创建一个实例,每次从容器中获取的都是同一个对象
	<bean id="student" class="com.blb.spring.Student" scope="singleton" >
		<property name="name" value="seven" />
	</bean>
5.4.2 原型模式
  • 原型模式下每次从容器中获取的都是一个新的对象
	<bean id="student" class="com.blb.spring.Student" scope="prototype" >
		<property name="name" value="seven" />
	</bean>
5.4.3 其它
  • ​ request、session、application只会在web项目中才能使用。

6. 依赖注入

  • 依赖注入(DI): Dependency Injection

  • 把有依赖关系的类放到容器中,解析出这些类的实例,就是依赖注入。

  • 依赖注入是实现IOC的一种方式。

  • IoC可以认为是一种全新的设计模式,但是理论和时间成熟相对较晚,并没有包含在GoF中。

6.1 构造器注入

已经讲过

6.2 Set注入

  1. bean定义

    public class Student {
         
    
    	private String  name ;
    
    	private String wife ;
    	
    	private int age ;
    	
    	private Course course ;
    	
    	private String [] hobby ;
    	
    	private List<String> game ;
    	
    	private Map<String,String> address ;
    	
    	private Set<String> girlFriends ;
    	
    	private Properties info ;
     	// getter/setter/toString   
    }
    
    public class Course {
         
    	
    	private String name  ;
    	
    	private String teacherName ;
    
    	// getter/setter/toString   
    }
    
  2. bean.xml

    <!-- 定义Sourse实例 -->
    <bean id="course" class="com.blb.spring.Course"> 
        <property name="courseName" value="百里半JAVA"/>
        <property name="teacherName" value="seven" />
    </bean>	
    <!-- 定义Student实例 -->
    <bean id="student" class="com.blb.spring.Student" >
        <!--  普通值注入 -->
        <property name="name"  value="张三"/>
        <!-- null值注入 -->
        <property name="wife">
            <null/>
        </property>		
        <!-- 普通值注入 -->
        <property name="age"   value="18"/>		
        <!-- 引用类型注入 -->
        <property name="course" ref="course" />		
        <!-- 数组值注入 -->
        <property name="hobby">
            <array>
                <value>打球</value>
                <value>打游戏</value>
                <value>看电影</value>
            </array>
        </property>		
        <!-- List值注入 -->
        <property name="game">
            <list>
                <value>王者荣耀</value>
                <value>地下城勇士</value>
                <value>吃鸡</value>
            </list>
        </property>		
        <!-- Map值注入 -->
        <property name="address">
            <map>
                <entry key="addr1"  value="武汉" /> 
                <entry key="addr2"  value="随州" /> 
                <entry key="addr3"  value="深圳" /> 
            </map>
        </property>		
        <!-- Set值注入 -->
        <property name="girlFriends">
            <set >
                <value>小红</value>
                <value>小丽</value>
                <value>小王</value>
            </set>
        </property>		
        <!-- prop值注入 -->
        <property name="info">
            <props>
                <prop key="age">18</prop>
                <prop key="height">180</prop>
                <prop key="weight" >180</prop>
            </props>
        </property>	
    </bean>
    
  3. 测试

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student = context.getBean("student",Student.class);
    System.out.println(student);
    

6.3 拓展方式注入

  • P命名空间注入:使用setter方式

    • bean:

      public class Student {
             
      	
      	private String name  ;
      	
      	private int age ;
      	
      	private Course course ;
          
          // getter/setter/toString
          
      }
      
    • 导入P命名空间

      xmlns:p="http://www.springframework.org/schema/p"
      
    • bean.xml

      <bean id="course" class="com.blb.spring.Course"> 
          <property name="courseName" value="百里半JAVA"/>
          <property name="teacherName" value
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值