2

学习Spring的第1天

 2 years ago
source link: https://blog.csdn.net/qq_41709577/article/details/121063207
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

学习Spring的第1天

框架:
Mybatis是用来解决和数据库进行交互的。
SpringMVC是用来替代我们写这些复杂的Web逻辑的。
Spring是一个容器框架。
EJB:Enterprise Java Bean

核心关注:IOC和AOP
容器:管理所有的组件;
组件:就是你写的那些类。
DI:Dependence Injection依赖注入。
AOP:Aspect Oriented Programming面向切面编程。

进入官网:
https://spring.io/
在这里插入图片描述
在这里插入图片描述
学好Spring就是学好IOC和AOP
Spring的模块;
1、Test模块:Spring的单元测试模块
2、Core Container:核心容器(IOC)
有beans,core,context,expression
3、AOP+Aspects:面向切面编程模块
4、数据访问:Spring数据访问模块
jdbc,orm(object relation mapping),tx(事务)
5、Web:Spring开发Web应用模块
web-socket
原生web
web-mvc

在这里插入图片描述

Inversion Of Control
控制反转
控制:控制资源的获取方式;(被动式)
资源的获取方式分为两种:主动式和被动式。
主动式:new的形式,要什么资源自己new
被动式:资源的获取不是cxy自己创建,而是交给一个容器来创建和设置。
容器:管理所有的组件(有功能的类。)
所以控制反转的意思就是,由以前主动new的形式,变成了被动的接收。

Dependency Injection
依赖注入。
容器可以知道哪个组件运行的时候,需要另外一个类。容器通过反射的形式,将容器中准备好的对象利用反射,给它复制。
给容器中注册组件。

现在准备测试Spring的IOC容器的功能。

在这里插入图片描述
1、导包
核心容器的四个jar包
beans,context,core,expression
在这里插入图片描述
在这里插入图片描述
导完这些包之后,还需要一个日志包。
因为Spring运行的时候依赖一个日志包,没有就会报错。

在这里插入图片描述
2、写配置。
配置文件里面由Spring的IOC容器管理的所有组件。
在这里插入图片描述
在这里插入图片描述
3、创建Person类。
在这里插入图片描述
4、开始在ioc.xml里面写一些配置。
在ioc.xml里面注册一个Person对象,Spring会自动创建这个Person对象
在这里插入图片描述
最大的标签是beans。
一个bean标签,可以注册一个组件
在这里插入图片描述

<bean class="com.rtl.bean.Person"></bean>

在这里插入图片描述
class:写要注册的组件的全类名。

<bean id="person01" class="com.rtl.bean.Person"></bean>

在这里插入图片描述
id:这个对象的唯一标识。
在这里插入图片描述

使用property标签为Person对象的属性赋值,
name指定属性名
value:为这个属性名赋值。
5、配置文件写好了之后,开始写测试类
ApplicationContext:这个类代表的是一个IOC容器。
ClassPathXmlApplicationContext:这是一个子类。代表通过xml文件的形式获取容器。

package com.rtl.test;

import com.rtl.bean.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class IOCTest {
    @Test
    public void test01(){
        ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
        Person p1 = (Person)ioc.getBean("person01");
        System.out.println(p1);
    }

}

测试结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
查看ioc.xml的位置。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
src里面的所有内容都会进入bin目录,而bin目录就是类路径的开始。
src下面直接有个ioc.xml,那么,在bin目录下直接也会有个ioc.xml
如果ioc.xml在src的com包下,那么对应bin下面的com包下也会有个ioc.xml
在这里插入图片描述

讲解细节:
1、ApplicationContext的继承树。

在这里插入图片描述
1、ClassPathXmlApplicationContext代表IOC容器的配置文件在类路径下面。
2、FileSystemXmlApplicationContext代表IOC容器的配置文件在磁盘路径下面。
我们从容器中按照id拿到了这个组件。
所以,Person对象的创建工作是由容器完成的。
问:Person对象是什么时候创建好了呢?
测试:
给Person的无参构造打印一句话:

public Person() {
        System.out.println("Person对象创建了");
    }

在这里插入图片描述
从这个测试中,我们发现了:
问:Person对象是什么时候创建好了呢?
答:
在容器创建完成的时候就已经创建好了。

执行这句话的时候,就已经创建好了。
 ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");

在这里插入图片描述
这个测试表明:
先创建好容器里面所有的对象。
第三个测试:
ioc.xml配置文件里面写了两个bean标签。
在这里插入图片描述
在这里插入图片描述
结论:
他会把容器里面所有的对象都创建好。

第四个测试:
在测试类里面,拿这个id=person01的对象拿两次,得到的这两个对象是同一个吗?
在这里插入图片描述
在这里插入图片描述
结论:是同一个对象。
同一个组件在ioc容器里面是单实例的。在容器启动的时候就已经创建准备好了。

测试五:
在这里插入图片描述
在容器里面跟根本没有person03这个组件。
在这里插入图片描述
结论:
容器中如果没有这个组件。获取组件的时候会发生异常。

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'person03' is defined

测试六:
在ioc.xml里面只有一个Person的bean标签
在这里插入图片描述
之前获取对象:都是通过id的名字来获取

Person p1 = (Person)ioc.getBean("person01");
Person p1 = ioc.getBean(Person.class);

但是需要注意的是:
如果通过这种形式的话,ioc.xml里面只能有一个Person的bean标签,否则会报错:
在这里插入图片描述
在这里插入图片描述

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.rtl.bean.Person] is defined: expected single matching bean but found 2: person01,person02

换种方式给属性赋值。

 <bean id="person01" class="com.rtl.bean.Person">
        <property name="lastName" value="张三"></property>
        <property name="age" value="18"></property>
        <property name="email" value="[email protected]"></property>
        <property name="gender" value="男"></property>
    </bean>

在这里插入图片描述
通过property属性赋值。
现在:
1、给Person类加上有参构造。
在这里插入图片描述

2、现在的ioc.xml

<bean id="person02" class="com.rtl.bean.Person">
        <constructor-arg name="lastName" value="张三"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="email" value="[email protected]"></constructor-arg>
        <constructor-arg name="gender" value="男"></constructor-arg>
    </bean>

在这里插入图片描述
测试类:
在这里插入图片描述

 public void test01(){
        ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
        Person p2 = ioc.getBean("person02",Person.class);
        System.out.println(p2);
    }

注意:
我们刚才讲的Person里面的属性的类型都是基本数据类型。
所以可以使用property标签进行赋值。

如果,属性类型有很多种类型呢,该怎么去ioc.xml里面写bean标签?

在这里插入图片描述

在这里插入图片描述
1、比如现在的Person类里面有个属性是Car类型
在这里插入图片描述
在这里插入图片描述

<bean id="car01" class="com.rtl.bean.Car">
        <property name="carName" value="宝马"></property>
        <property name="price" value="19000"></property>
        <property name="color" value="绿色"></property>
    </bean>
    <bean id="person03" class="com.rtl.bean.Person">
        <property name="lastName" value="张三"></property>
        <property name="age" value="18"></property>
        <property name="email" value="[email protected]"></property>
        <property name="gender" value="男"></property>
        <property name="car" ref="car01"></property>
    </bean>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
他们是同一个Car对象。

这个是引用外部bean的方式,现在还有内部形式:

<bean id="person03" class="com.rtl.bean.Person">
        <property name="lastName" value="张三"></property>
        <property name="age" value="18"></property>
        <property name="email" value="[email protected]"></property>
        <property name="gender" value="男"></property>
        <property name="car">
            <bean id="car01" class="com.rtl.bean.Car">
                <property name="color" value="宝马2"></property>
            </bean>
        </property>
    </bean>

对比一下:
在这里插入图片描述
在这里插入图片描述

如果Person里面有个属性是List?

在这里插入图片描述
在这里插入图片描述

<bean id="person04" class="com.rtl.bean.Person">
        <property name="lastName" value="张三"></property>
        <property name="age" value="18"></property>
        <property name="email" value="[email protected]"></property>
        <property name="gender" value="男"></property>
        <property name="car" ref="car01"></property>
        <property name="books">
            <list>
                <bean id="book01" class="com.rtl.bean.Book">
                    <property name="author" value="吴承恩"></property>
                    <property name="bookName" value="西游记"></property>
                </bean>
            </list>
        </property>
    </bean>

在这里插入图片描述
测试类:
在这里插入图片描述

  @Test
    public void test01(){
        ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
        Person p4 = ioc.getBean("person04",Person.class);
        System.out.println(p4);
        List<Book> books = p4.getBooks();
        for (Book book : books) {
            System.out.println(book);
        }
    }

在这里插入图片描述
结论:Person里面有个属性是List<…>,使用list标签。

注意:
内部的bean,是不能获取的。
看:
在这里插入图片描述
测试类:

Book book01 = ioc.getBean("book01", Book.class);
        System.out.println(book01);

在这里插入图片描述
报错信息:
在这里插入图片描述

如果Person对象里面有个属性是Map对象呢?

使用map标签和entry标签。
一个map,就相当于new了一个LinkedHashMap
一个entry相当于K-V键值对。
在这里插入图片描述
这个map里面一共有四个键值对。
在这里插入图片描述
在这里插入图片描述

问:容器里面创建对象有顺序吗?
有的。
按照配置文件里面写的顺序来创建。
bean之间的依赖,只是改变创建的顺序。

测试bean的作用域。分别创建单实例和多实例的bean

bean的作用域的意思就是:这个bean是否是单实例的?默认是单实例的。
在这里插入图片描述


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK