Spring笔记

本文详细介绍了Spring框架,包括其优点、体系架构以及IoC(控制反转)和DI(依赖注入)的概念。通过XML配置文件和注解两种方式演示了如何创建Spring项目,讲解了set注入、构造注入以及引用类型的自动注入。此外,还讨论了基于注解的DI,如@Component、@Autowired和@Resource的使用。最后,简要介绍了Spring的AOP(面向切面编程)概念、通知类型和切入点表达式,以及Spring与MyBatis的集成流程。
摘要由CSDN通过智能技术生成

Spring

文章目录

1. Spring框架

1.1 概述

Spring 是于2003 年兴起的一个轻量级的Java 开发框架,它是为了解决企业应用开发的复杂性而创建的。Spring的核心是控制反转(IoC)和面向切面编程(AOP)。Spring是可以在Java SE/EE中使用的轻量级开源框架。

Spring的主要作用就是为代码“解耦”,降低代码间的耦合度。就是让对象和对象(模块和模块)之间关系不是使用代码关联,而是通过配置来说明。即在Spring中说明对象(模块)的关系。

Spring根据代码的功能特点,使用Ioc降低业务对象之间耦合度。IoC使得主业务在相互调用过程中,不用再自己维护关系了,即不用再自己创建要使用的对象了。而是由Spring 容器统一管理,自动“注入”,注入即赋值。而AOP使得系统级服务得到了最大复用,且不用再由程序员手工将系统级服务“混杂”到主业务逻辑中了,而是由Spring容器统一完成“织入”。

官网: https://spring.io/

1.2 优点

  1. 轻量:Spring的所需要的jar包都非常小,一般1M以下,几百kb。核心功能所需要的jar包总共3M左右。
    Spring框架运行占有资源少,运行效率高,不依赖其他jar。、
  2. 针对接口编程,解耦合
  3. AOP 编程的支持
  4. 方便集成各种优秀框架

1.3 Spring体系架构

Spring 由 20 多个模块组成,它们可以分为数据访问/集成(Data Access/Integration)、 Web、面向切面编程(AOP, Aspects)、提供JVM的代理 (Instrumentation)、消息发送(Messaging)、 核心容器(Core Container)和测试(Test)。

2. IoC控制反转

2.1 概述

控制反转(IoC,Inversion of Control):是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值,依赖的管理。

控制:创建对象,对象的属性赋值,对象之间的关系管理。
反转:把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。 由容器代替开发人员管理对象。创建对象,属性赋值。

正转:由开发人员在代码中,使用new 构造方法创建对象, 开发人员主动管理对象。

public static void main(String args[]){
   
	Student student = new Student(); // 在代码中, 创建对象。--正转。
}

容器:是一个服务器软件, 一个框架(spring)

使用 ioc 目的: 减少对代码的改动,也能实现不同的功能。 实现解耦合。

java中创建对象有哪些方式:

  1. 构造方法 , new Student()
  2. 反射
  3. 序列化
  4. 克隆
  5. ioc :容器创建对象
  6. 动态代理

IoC的技术实现:
依赖注入(DI,Dependency Injection):依赖注入, 只需要在程序中提供要使用的对象名称就可以, 至于对象如何在容器中创建,赋值,查找都由容器内部实现。

spring是使用的di实现了ioc的功能, spring底层创建对象,使用的是反射机制。

spring是一个容器,管理对象,给属性赋值, 底层是反射创建对象。

2.2 创建一个Spring项目

2.2.1 创建maven项目,并导入spring依赖

导入依赖:

<dependencies>
    <!--单元测试:通过单元测试可以测试每一个方法-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
     <!--Spring的依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
</dependencies>
2.2.2 创建业务接口与实现类

接口:

public interface SomeService {
   
    void doSome();
}

实现类:

public class SomeServiceImpl implements SomeService {
   
    
    @Override
    public void doSome() {
   
        System.out.println("====SomeServiceImpl业务方法doSome=====");
    }
}

ps:spring默认调用无参数构造方法创建对象

2.2.3 创建Spring配置文件

在 src/main/resources/目录下创建一个 xml 文件,文件名随意,但Spring 建议的名称为 applicationContext.xml。 IDEA已经设计好了Spring配置文件的模板:
右击resources–>new–>XML configuration file–>Spring 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="someService" class="com.sqt.service.impl.SomeServiceImpl" />
    <bean id="someService1" class="com.sqt.service.impl.SomeServiceImpl" scope="prototype"/>

    <!--
       spring创建一个非自定义类的对象, 创建一个存在的某个类的对象。
    -->
    <bean id="mydate" class="java.util.Date" />

</beans>
<!--
    spring的配置文件
    1.beans : 是根标签,spring把java对象成为bean。
    2.spring-beans.xsd 是约束文件,和mybatis指定  dtd是一样的。
-->

声明bean ,告诉spring要创建某个类的对象:

  • id:对象的自定义名称,唯一值。 spring通过这个名称找到对象

  • class:类的全限定名称(不能是接口,因为spring是反射机制创建对象,必须使用类)

  • scope:指定bean对象的作用域(对象的存在范围和可见性)。可取值:

    • 单例:singleton , 默认值,表示叫这个名称的对象在spring容器中只有一个。
    • 原型:prototype , 表示每次使用getBean()都创建一个新的对象。

spring就完成 SomeService someService = new SomeServiceImpl();

spring是把创建好的对象放入到map中, spring框架有一个map存放对象的。
springMap.put(id的值, 对象);

例如 :springMap.put("someService", new SomeServiceImpl());

一个bean标签声明一个对象。

2.2.4 创建测试类
@Test
public void test01(){
   

    //定义Spring的配置文件, 配置文件是在类路径的根目录之下
    String config = "applicationContext.xml";

    //创建Spring的容器对象.根据Spring配置文件的位置,使用接口的不同实现类
    //1.如果Spring的配置文件是在类路径(classpath),使用ClassPathXmlApplicationContext
    //2.如果Spring的配置文件是放在项目的根之下(与src、target同级目录),使用FileSystemXmlApplicationContext
    //创建Spring容器,会读取配置文件中的bean标签,并创建对应的对象。
    ApplicationContext ctx = new ClassPathXmlApplicationContext(config);

    //从容器中获取对象 使用getBean("<bean>的id")
    SomeService service = (SomeService) ctx.getBean("someService");

    //调用业务方法
    service.doSome();
}

2.3 基于XML的DI

通过在xml配置文件对对象的属性进行赋值。

di的实现有两种:

  1. 在spring的配置文件中, 使用标签和属性完成,叫做基于XML的di实现

  2. 使用spring中的注解,完成属性赋值, 叫做基于注解的id实现

di的语法分类:

  1. set注入(设置注入): spring调用类的set方法,在set方法可以实现属性的赋值。
    80左右都是使用的set注入

  2. 构造注入,spring调用类的有参数构造方法,创建对象。在构造方法中完成赋值。

2.3.1 set注入

set注入也叫设值注入是指,通过setter方法传入被调用者的实例。这种注入方式简单、直观,因而在Spring的依赖注入中大量使用。

简单类型(Java中的基本类型和String类型)

实体类:

public class Student {
   

    private String name;
    private int age;

    /*
    	需要有set方法,没有set方法是报错的。
    	Bean property 'name' is not writable or has an invalid setter method
    */
   public void setName(String name) {
   
        this.name = name.toUpperCase();
    }

    public void setAge(int age) {
   
        this.age = age;
    }
    
    public void setEmail(String email){
   
        System.out.println("setEmail="+email);
    }
}   

applicationContext.xml:

<!--声明student对象
	<bean id="xx" class="yyy">
		<property name="属性名字" value="此属性的值"/>
		一个property只能给一个属性赋值
		<property.sqt..sqt.>
	</bean>
-->
<bean id="myStudent" class="com.sqt.ba01.Student" >
    <property name="name" value="李四lisi" /><!--setName("李四")-->
    <property name="age" value="22" /><!--setAge(21)-->
    <property name="email" value="lisi@qq.com" /><!--setEmail("lisi@qq.com")-->
</bean>
引用类型:

当指定 bean 的某属性值为另一 bean 的实例时,通过 ref 指定它们间的引用关系。ref 的 值必须为某 bean 的 id 值。

实体类:(都有set方法)

public class School {
   
    private String name;
    private String address;
}
public class Student {
   
    private String name;
    private int age;

    //声明一个引用类型
    private School school;
}

applicationContext.xml:

<bean id="xxx" class="yyy">
	<property name="属性名称" ref="bean的id(对象的名称)" />
</bean>
<bean id="myStudent" class="com.sqt.ba02.Student" >
    <property name="name" value="李四" />
    <property name="age" value="26" />
    <!--引用类型-->
    <property name="school" ref="mySchool" /><!--setSchool(mySchool)-->
</bean>

<!--声明School对象-->
<bean id="mySchool" class="com.sqt.ba02.School">
	<property name="name" value="北京大学"/>
    <property name="address" value="北京的海淀区" />
</bean>
2.3.2 构造注入(了解)

构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系。

给实体类添加构造器:

//定义有参数构造方法
public  Student(String myname, int myage, School mySchool){
   
    System.out.println("Student有参数构造方法");
    //给属性完成赋值
    this.name = myname;
    this.age  = myage;
    this.school = mySchool;
}

applicationContext.xml:

标签:一个表示构造方法一个参数。
标签属性:

  • name:表示构造方法的形参名
  • index:表示构造方法的参数的位置,参数从左往右位置是 0 , 1 ,2的顺序
  • value:构造方法的形参类型是简单类型的,使用value
  • ref:构造方法的形参类型是引用类型的,使用ref
	<!--使用name属性实现构造注入-->
    <bean id="myStudent" class="com.sqt.ba03.Student" >
        <constructor-arg name="myage" value="20" />
        <constructor-arg name="mySchool" ref="myXueXiao" />
        <constructor-arg name="myname" value="周良"/>
    </bean>

    <!--使用index属性-->
    <bean id="myStudent2" class="com.sqt.ba03.Student">
        <constructor-arg index="1" value="22" />
        <constructor-arg index="0" value="李四" />
        <constructor-arg index="2" ref="myXueXiao" />
    </bean>

    <!--省略index-->
    <bean id="myStudent3" class="com.sqt.ba03.Student">
        <constructor-arg  value="张强强" />
        <constructor-arg  value="22" />
        <constructor-arg  ref="myXueXiao" />
    </bean>
    <!--声明School对象-->
    <bean id="myXueXiao" class="com.sqt.ba03.School">
        <property name="name" value="清华大学"/>
        <property name="address" value="北京的海淀区" />
    </bean>
2.3.3 引用类型的自动注入

对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为标签 设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属 性)。根据自动注入判断标准的不同,可以分为两种:

  • byName:根据名称自动注入
  • byType: 根据类型自动注入
byName

当配置文件中被调用者 bean 的 id 值与代码中调用者 bean 类的属性名相同时,可使用 byName 方式,让容器自动将被调用者 bean 注入给调用者 bean。容器是通过调用者的 bean 类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的。

java类中引用类型的属性名和spring容器中(配置文件)的id名称一样,且数据类型是一致的,这样的容器中的bean,spring能够赋值给引用类型。

  <bean id="xx" class="yyy" autowire="byName">
     简单类型属性赋值
  </bean>
<!--byName-->
<bean id="myStudent" class="com.sqt.ba04.Student"  autowire="byName">
    <property name="name" value="李四" />
    <property name="age" value="26" />
    <!--引用类型-->
    <!--<property name="school" ref="mySchool" />-->
</bean>

<!--声明School对象-->
<bean id="school" class="com.sqt.ba04.School">
    <property name="name" value="清华大学"/>
    <property name="address" value="北京的海淀区" />
</bean>
byType

byType(按类型注入) :java类中引用类型的数据类型和spring容器中(配置文件)的class属性是同源关系的,这样的bean能够赋值给引用类型.

同源就是一类的意思:

  1. java类中引用类型的数据类型和bean的class的值是一样的。
  2. java类中引用类型的数据类型和bean的class的值父子类关系的。
  3. java类中引用类型的数据类型和bean的class的值接口和实现类关系的
<bean id="xx" class="yyy" autowire="byType">
    简单类型属性赋值
</bean>

注意:在byType中, 在xml配置文件中声明bean只能有一个符合条件的,多余一个是错误的
<!--byType-->
<bean id="myStudent" class="com..ba05.Student"  autowire="byType">
    <property name="name" value="张飒" />
    <property name="age" value="26" />
    <!--引用类型-->
    <!--<property name="school" ref="mySchool" />-->
</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值