拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Spring系列2:Spring容器基本概念和使用

Spring系列2:Spring容器基本概念和使用

白鹭 - 2022-03-02 1954 0 0

本文内容

  1. 简单回顾IoC和DI概念
  2. Spring容器的概念
  3. 的xml配置和初始化
  4. 容器的基本使用
  5. bean的定义和初始化配置

简单理解IoC和DI概念

什么是IoC控制反转?

通俗地但不严谨地讲,以前传统方式都是应用程序需要一个物件,直接通过new的方式来生成,该物件的管理也是由当前程序自己控制,现在有一个容器,负责将应用程序需要的所有物件都new好了,物件都统一由这个容器管理,应用程序需要物件的时候直接找容器要,应用程序说我不关系物件是怎么来的反正你给我就行,这样和以前的方式不一样了,以前是应用程序自己创建和管理,现在交给容器统一创建管理了,控制权发生反转了,这简单理解为IoC,

什么是DI依赖注入?

通俗地但不严谨地讲,应用程序需要的物件A依赖于B,由容器直接自动将B依赖给到物件A,可以理解为自动将依赖B注入到A 中了,

Spring官方的对于这个2个概念的说明,比较绕,这里也附上,

Spring容器的概念和使用

Spring IoC容器负责实体化、配置和组装bean,容器通过读取配置元资料来获取关于实体化、配置和组装哪些物件的指令,配置元资料以XML、Java注释或Java代码表示,

下面将通过一个案例来快速演示Spring容器的简单使用,

环境准备

IDE: IDEA

Maven: 3.5.6

JDK: java8

创建Maven工程并Spring引入依赖

pom档案如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>spring-ioc-quickstart</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.verison>5.2.19.RELEASE</spring.verison>
    </properties>

    <dependencies>
        <!--Spring背景关系的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.verison}</version>
        </dependency>
    </dependencies>

    <build>
        <!--组态档相关-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
</project>

创建2个简单类A、B

A依赖B如下

public class A {
    private B b;

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }
}

B如下

public class B {
}

创建Spring的XML组态档

resources目录创建spring.xml组态档,并配置bean

<?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">

    <!--A的定义信息-->
    <bean id="a" >
        <!--注入B物件依赖-->
        <property name="b" ref="b"/>
    </bean>

    <!--B的定义信息-->
    <bean id="b" ></bean>
</beans>

创建一个测验类

public class MainTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        A a = context.getBean("a", A.class);
        B b = context.getBean("b", B.class);
        System.out.println("A物件:" + a);
        System.out.println("A物件中的B依赖: " + a.getB() );
        System.out.println("B物件:" + b);
    }
}

最终档案目录结构

image-20220112120030437

运行结果

物件AB都统一由ClassPathXmlApplicationContext容器管理,并在A需要B依赖的时候容器自动注入,应用程序需要的时候直接从容器拿界面如context.getBean(),,结合着里面下IoC和DI的概念,以上就是Spring容器的简单使用,

A物件:com.crab.spring.A@2d928643
A物件中的B依赖: com.crab.spring.B@5025a98f
B物件:com.crab.spring.B@5025a98f

Spring 容器物件

BeanFactory 界面

BeanFactory 界面提供了一种高级配置机制,能够管理任何型别的物件,是Spring IoC容器根界面,主要的定义方法如下,

package org.springframework.beans.factory;

public interface BeanFactory {
    // 指定名称获取bean
    Object getBean(String name) throws BeansException;
    // 指定名称和型别获取bean
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	// 指定型别获取bean
	<T> T getBean(Class<T> requiredType) throws BeansException;
	// 容器中是否存在bean
	boolean containsBean(String name);
    // 是否是单例
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    
    //
}

ApplicationContext界面

ApplicationContext界面是BeanFactory的子界面,在其基础上提供更多企业级的功能,负责实体化、配置和组装bean,支持xml组态档、java注解、Java-based等方式进行bean的配置,常使用的实作类有: ClassPathXmlApplicationContextFileSystemXmlApplicationContextAnnotationConfigApplicationContext等,后面详细讲解和使用,请保持阅读的热情,

bean定义物件

在 Spring 中,构成应用程序并由 Spring IoC 容器管理的物件称为 bean,这些 bean 是使用提供给容器的配置元资料创建的,如以 XML 定义的形式,

<!--A的定义信息-->
<bean id="a" >
    <!--注入B物件依赖-->
    <property name="b" ref="b"/>
</bean>

xml中<bean />配置格式和支持元素如下:

<bean id="myChild" 
      init-method="init"
      destroy-method="destroy"
      name="childBean,aliasName"
      parent="myParent"
      scope="singleton"
      primary="true"
      depends-on="myParent"
      autowire="byType"
      autowire-candidate="true"
      factory-bean="myFactory"
      factory-method="getObj"
      abstract="false"
      ></bean>
元素 说明
id 唯一ID
class 对应的类,全路径
name 支持名称,可以逗号/分号/空格来分隔多个,多个名称可用作别名
init-method 自定义的初始化方法
destroy-method 自定义的bean被销毁的方法
parent 指定父类参考
scope 指定作用域,如单例和原型,后面详细讲
primary 是否是主要的,用于依赖注入时候容器内有多个同型别的bean时做选择
depends-on 依赖于容器中的另外一个bean的参考
autowire 自动注入依赖,指定通过名称或是型别
autowire-candidate 标记自动依赖注入时候选
factory-bean 指定创建该bean的工厂
factory-method 指定创建的工厂方法
abstract 是否是抽象
lazy-init 延迟加载

在Spring容器内,bean的定义信息最终是通过界面BeanDefinition及其实作类体现,BeanDefinition界面和抽象类AbstractBeanDefinition`,主要定义如下

package org.springframework.beans.factory.config;

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	void setParentName(@Nullable String parentName);
	void setBeanClassName(@Nullable String beanClassName);
	void setScope(@Nullable String scope);
	void setLazyInit(boolean lazyInit);
	void setDependsOn(@Nullable String... dependsOn);
	void setAutowireCandidate(boolean autowireCandidate);
	void setPrimary(boolean primary);
	void setFactoryBeanName(@Nullable String factoryBeanName);
	void setFactoryMethodName(@Nullable String factoryMethodName);
	void setInitMethodName(@Nullable String initMethodName);
	void setDestroyMethodName(@Nullable String destroyMethodName);
    // 省略
}

package org.springframework.beans.factory.support;

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
		implements BeanDefinition, Cloneable {
	private volatile Object beanClass;
	private String scope = SCOPE_DEFAULT;
	private boolean abstractFlag = false;
	private Boolean lazyInit;
	private int autowireMode = AUTOWIRE_NO;
	private String[] dependsOn;
	private boolean autowireCandidate = true;
	private boolean primary = false;
	private String factoryBeanName;
	private String factoryMethodName;
	private String initMethodName;
	private String destroyMethodName;
}

总结

本文主要讲解了Ioc的概念,演示Spring Ioc容器的快速使用,并详细说明bean定义元素,下一篇将讲bean的依赖注入,

知识分享,转载请注明出处,学无先后,达者为先!

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *