Spring5学习总结(一)IoC底层原理/工厂模式/创建对象/注入属性/依赖注入/IoC和DI的区别/基于XML实现Bean管理/Bean的生命周期/基于注解实现Bean管理/完全注解开发

一、Spring概述

  • Spring 是轻量级开源的 JavaEE 框架
  • Spring 可以解决企业应用开发的复杂性
  • Spring 有两个核心部分:IoCAOP
    (1)IoC:(Inversion of Control) 指控制反转或反向控制。在Spring框架中我们通过配置创建类对象,由Spring在运行阶段实例化、组装对象。(把创建对象过程交给 Spring 进行管理)
    (2)AOP:(Aspect Oriented Programming)面向切面编程,其思想是在执行某些代码前执行另外的代码,使程序更灵活、扩展性更好,可以随便地添加、删除某些功能。Servlet中的Filter便是一种AOP思想的实现
  • Spring 特点
    (1)方便解耦,简化开发
    (2)AOP 编程支持
    (3)方便程序测试
    (4)方便和其他框架进行整合
    (5)方便进行事务操作
    (6)降低 API 开发难度

二、入门案例

  1. 下载 Spring5
    在这里插入图片描述

  2. 打开 idea 工具,创建普通 Java 工程

  3. 导入 Spring5 相关 jar 包,并添加依赖
    Spring核心容器:在这里插入图片描述
    因此我们需要导入上面四个包,另外我们还需要一个管理日志的包commons-logging.jar在这里插入图片描述
    建一个lib目录,复制jar包进来——>FILE——>Project Structure——>Modules——>Dependencies——>"+"——>JARs or directories——>添加需要的jar包依赖
    在这里插入图片描述

  4. 创建普通类,在这个类创建普通方法

public class User {
   
    public void hello(){
   
        System.out.println("hello world");
    }
}
  1. 创建 Spring 配置文件,在配置文件配置创建的对象
    Spring 配置文件使用 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">
    <!--配置User对象创建-->
    <!--id:唯一标识(别名) class:全类名-->
    <bean id="user" class="com.fox.bean.User"></bean>
</beans>
  1. 进行测试代码编写
import com.fox.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
   
    public static void main(String[] args) {
   
        //1 加载 spring 配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        //2 获取配置创建的对象
        User user = context.getBean("user", User.class);
        System.out.println(user);
        user.hello();
    }
}

在这里插入图片描述

三、IoC详解

(一)概念和原理

1.什么是IoC

  • IoC(Inversion of Control) 指控制反转或反向控制。在Spring框架中我们通过配置创建类对象,由Spring在运行阶段实例化、组装对象。(把创建对象过程交给 Spring 进行管理)
  • 使用 IoC 目的:为了降低耦合度
  • 什么是反转
    反转是相对于正向而言的,那么什么算是正向的呢?考虑一下常规情况下的应用程序,如果要在A里面使用C的方法,你会怎么做呢?当然是直接去创建C的对象,也就是说,是在A类中主动去获取所需要的外部资源C,这种情况被称为正向的。那么什么是反向呢?就是A类不再主动去获取C,而是被动等待,等待IoC的容器获取一个C的实例,然后反向的注入到A类中。

2.IoC底层原理

IoC是通过xml解析、工厂模式、反射共同实现的

(1)什么是工厂模式

该模式用于封装和管理对象的创建,是一种创建型模式。工厂模式的本质就是用工厂方法代替new操作创建一种实例化对象的方式。工厂模式可以降低耦合度。一句话中总结就是方便创建同种类型接口产品的复杂对象
案例
假如我们需要在一个类的方法中调用另一个类的方法,那么原始方式如下:
在这里插入图片描述
我们会发现,这样的方式,两个类的耦合度十分高,那么我们可以利用工厂模式进行优化:
在这里插入图片描述
耦合度是不能完全消除的,只能最大限度降低耦合度

(2)为什么要用工厂模式
  • 解耦:把对象的创建和使用的过程分开。假如Class A 想调用 Class B ,而A只是想调用B的方法,至于B的实例化,就交给工厂类。
  • 降低代码重复:如果创建某个对象的过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。
  • 降低维护成本:由于创建过程都由工厂统一管理,所以发生业务逻辑变化,不需要找到所有需要创建某个对象的地方去逐个修正,只需要在工厂里修改即可,降低维护成本。
(3)理解IoC底层原理

举个不恰当的例子:就像找女朋友,如果我们自己找,就要想办法认识她们,投其所好送其所要,我们必须自己设计和面对每个环节,充满了耦合;而IoC就类似婚介帮我们找女朋友,婚介会按照我们的要求,提供一个女生,我们只需要去和她谈恋爱、结婚就行了。
在这里插入图片描述

(二) IoC 容器两种接口

IoC 思想基于 IoC 容器完成,IoC 容器底层就是对象工厂

Spring 提供了 IoC 容器两种实现方式:(两种接口)
(1)BeanFactory:IoC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用

//加载 spring 配置文件
BeanFactory context = new ClassPathXmlApplicationContext("bean1.xml");

(2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用

//加载 spring 配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");

BeanFactory和ApplicationContext最大的区别

  • 用BeanFactory加载配置文件时候不会创建对象,在获取(使用)对象时才去创建对象
  • 用ApplicationContext加载配置文件时候就会把在配置文件的对象进行创建
  • 你可能会觉得要用时才创建的Beanfactory节省资源,但是还是推荐ApplicationContext,因为它可以在Tomcat服务器启动时(最耗时耗资源的阶段)把创建对象的工作给一并解决

ApplicationContext 接口有两个常用的实现类
在这里插入图片描述
如果你的xml配置文件是在本地某盘符下,就可以用FileSystemXmlApplicationContext加载配置文件,而如果你的xml配置文件就在本项目的src下,就可以用ClassPathXmlApplicationContext加载配置文件。

(三)Bean管理

1.什么是 Bean 管理

  • Bean 管理指的是两个操作
    • Spring 创建对象
    • Spring 注入属性
  • Bean 管理操作有两种方式:
    • 基于 xml 配置文件方式实现
    • 基于注解方式实现

2.基于xml配置文件方式实现Bean管理

(1)创建对象
<bean id="user" class="com.fox.bean.User"></bean>
  • 在 spring 配置文件中,使用 bean 标签,标签里面添加对应属性,就可以实现对象创建
  • 在 bean 标签中有很多属性,其中常用的属性:
    • id 属性:唯一标识(别名)
    • class 属性:类全路径
    • name属性:类似id属性,但它可以包含特殊字符如“/”(name属性是早期为Structs1使用的,现在用得少)
  • 创建对象时候,默认也是执行无参构造方法完成对象创建
(2)注入属性

在讲注入属性前,我们要先了解一个概念:DI(Dependency Injection),依赖注入

①什么是DI(依赖注入)
  • 是指spring框架在创建bean对象时,动态的将依赖对象注入到bean组件中。组件之间依赖关系由容器在运行期决定,形象的说,依赖注入即由容器动态地将某个依赖关系注入到组件之中。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
  • 理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:
    • 谁依赖于谁:当然是对象依赖于IoC容器;
    • 为什么需要依赖:对象需要IoC容器来提供对象需要的外部资源;
    • 谁注入谁:很明显是IoC容器注入应用程序某个对象
    • 注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
②IoC和DI的区别:
  • 控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。把对象的创建、初始化、销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。即是将new 的过程交给spring容器去处理;
    DI依赖注入是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。依赖注入是目前最优秀的解耦方式。依赖注入让Spring的Bean之间以配置文件的方式组织在一起,而不是以硬编码的方式耦合在一起的。
  • DI是IoC中一种具体实现,DI的实现依赖于IoC,先有控制反转才有依赖注入(依赖注入需要在创建对象的基础上才能进行)。相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。
  • IoC模式太普遍,任何框架都是IoC,为了让表意更明确,决定用DI来精确指称这个模式。
    举个不恰当的例子:
    IoC ioc = the_pattern;
    DI di = (DI)ioc;
    显然,说the_pattern是IoC或DI都行。但严格说IoC.class == DI.class肯定不为真,两者还是有区别,是 is a 的关系。
③第一种注入属性方式:使用 set 方法进行注入

1、创建类,定义属性和对应的 set 方法

public class Book {
   
    //创建属性
    private String bname;
    private String bauthor;
    //创建属性对应的 set 方法
    public void setBname(String bname) {
   
   	    this.bname = bname;
 	}
 	public void setBauthor(String bauthor) {
   
	    this.bauthor = bauthor;
 	} 
 	@Override
    public String toString() {
   
        return "Book{" +
                "bname='" + bname + '\'' +
                ", bauthor='" + bauthor + '\'' +
                '}';
    }
}

2、在 spring 配置文件配置对象创建,配置属性注入

<?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="book" class="com.fox.bean.Book">
	 <!--使用 property 完成属性注入
	 name:类里面属性名称
	 value:向属性注入的值
	 -->
		<property name="bname" value="Java从入门到放弃"></property>
		<property name="bauthor" value="小明"></property>
	</bean>
</beans>

3、测试类

import com.fox.bean.Book;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
   
    public static void main(String[] args) {
   
        //1 加载 spring 配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        //2 获取配置创建的对象
        Book book = context.getBean("book", Book.class);
        System.out.println(book);
    }
}

在这里插入图片描述

④第二种注入属性方式:使用有参数构造进行注入

1、创建类,定义属性,创建属性对应的有参构造方法

public class Book {
   
    //创建属性
    private String bname;
    private String bauthor;
    //创建属性对应的有参构造方法
    public Book(String bname,String bauthor){
   
        this.bname=bname;
        this.bauthor=bauthor;
    }
    @Override
    public String toString() {
   
        return "Book{" +
                "bname='" + bname + '\'' +
                ", bauthor='" + bauthor + '\'' +
                '}';
    }
}

2、在 spring 配置文件中进行配置
配置了constructor-arg组件以后,spring创建对象时就是使用的有参构造方法而不再是无参构造方法

<?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="book" class="com.fox.bean.Book">
     	<constructor-arg name="bname" value="Java从入门到放弃"></constructor-arg>
     	<constructor-arg name="bauthor" value="小明"></constructor-arg>
<!--        也可以用index取代name,index="0"代表此类的第一个属性,以此类推:-->
<!--        <constructor-arg index="0" value="Java从入门到放弃"></constructor-arg>-->
<!--        <constructor-arg index="1" value="小明"></constructor-arg>-->
	</bean>
</beans>

3、测试类

import com.fox.bean.Book;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
   
    public static void main(String[] args) {
   
        //1 加载 spring 配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        //2 获取配置创建的对象
        Book book = context.getBean("book", Book.class);
        System.out.println(book);
    }
}

在这里插入图片描述

⑤p名称空间注入(了解)

这个其实也是set方法进行注入的一种简化形式

1、创建类,定义属性和对应的 set 方法

public class Book {
   
    //创建属性
    private String bname;
    private String bauthor;
    //创建属性对应的 set 方法
    public void setBname(String bname) {
   
   	    this.bname = bname;
 	}
 	public void setBauthor(String bauthor) {
   
	    this.bauthor = bauthor;
 	} 
 	@Override
    public String toString() {
   
        return "Book{" +
                "bname='" + bname + '\'' +
                ", bauthor='" + bauthor + '\'' +
                '}';
    }
}

2、我们需要添加 p 名称空间到配置文件中

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

    <bean id="book" class="com.fox.bean.Book" p:bname="Java从入门到放弃" p:bauthor="小明">
    </bean>
</beans>

3、测试类

import com.fox.bean.Book;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
   
    public static void main(String[] args) {
   
        //1 加载 spring 配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        //2 获取配置创建的对象
        Book book = context.getBean("book", Book.class);
        System.out.println(book);
    }
}

在这里插入图片描述

⑥xml 注入其他类型属性
Ⅰ.注入字面量

1)注入null值:

<?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="book" class="com.fox.bean.Book">
        <property name="bname" value="Java从入门到放弃"></property>
        <!--给属性设置空值-->
        <property name="bauthor">
            <null/>
        </property>
    </bean>
</beans>

在这里插入图片描述

2)注入包含特殊符号的属性值:
需求:书名需要添加<<>>这个特殊符号

  • 方式一,利用转义字符:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi=
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值