Spring 注入相关(XML 构造器注入)

看Spring 依赖注入,发现了XML 注入。怕忘记了= =翻书毕竟不方便 QAQ

这边写了一个小Demo。直接先上代码吧= =

package com.core.spring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.http.converter.json.GsonBuilderUtils;
import org.w3c.dom.ls.LSOutput;

/**
 * @Auther WangYifei
 * @To LiuXuemei
 * @Date 2020/2/10 13:41
 * 加油?加油!
 */
public class Employee {


    public static void main(String[] args) {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("config.xml");
        WangYifei wangYifei = classPathXmlApplicationContext.getBean(WangYifei.class);
        if (wangYifei.getConfig() != null) {
            wangYifei.getConfig().sayOk();
        }
    }
}

class Config{
    public void sayOk(){
        System.out.println("Hello World!");
    }
}

class WangYifei{
    private Config config;

    WangYifei(Config config){
        this.config = config;
    }

    public Config getConfig() {
        if(this.config == null){
            System.out.println("我没有注入成功");
            return this.config;
        }else {
            System.out.println("我注入进来了 -> " + this.config);
            return this.config;
        }
    }
}

出于方便,直接在一个class文件定义三个类,一个用于查看结果,一个用于被注入,一个用于注入。
Employee 用于查看结果,Config 用于被注入,WangYifei 用于构造器注入。
声明一下,这里的类名没有什么特殊含义。

首先我们看Config这个类,里面只是定义了一个方法,sayOk(),然后放在一边,不管它。

再看WangYifei这个类,里面定义了一个属性,然后一个构造器。

WangYifei(Config config){
        this.config = config;
    }

这个构造器就是关键了,形参里面定义了Config这个类,这个时候不知道怎么注入的。先不管它。
现在只需要知道,构造器注入,肯定跟构造器有关,肯定需要传值给构造器,之后赋值给本类属性。

之后定义了一个getConfig的方法,用于输出Config,为了效果明显,给了一个判断是否注入成功的判断。

public Config getConfig() {
        if(this.config == null){
            System.out.println("我没有注入成功");
            return this.config;
        }else {
            System.out.println("我注入进来了 -> " + this.config);
            return this.config;
        }
    }

如果 this.config, 也就是本类的Config对象为null,表示并没有引用任何对象也就是注入失败了。
并且都返回这个this.config对象,为什么不直接说Config对象,因为我觉得可能会有不引用的可能,不能完全肯定

好了,验证代码先不看。我们直接看一下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="wangyifei" class="com.core.spring.test.WangYifei">
       <constructor-arg ref="configBean"></constructor-arg>
   </bean>

   <bean id="configBean" class="com.core.spring.test.Config">
   </bean>
</beans>

多说一句= =,我觉得Spring的话,主要就是这个Bean对象,应该是Spring的核心,但是还没仔细看= =到后面再看看QAQ

这里定义了两个bean,一个id 为 wangyifei,一个id 为configBean,并为它们依次指定类。

com.core.spring.test.WangYifei
com.core.spring.test.Config

在id 为wangyifei 的bean 可以看出,多了一个标签,就是 constructor-arg 这个标签是干嘛的呢,就是用于给当前类 也就是WangYifei => 这个类中的构造器传入对象,也就是注入了引用了 id 为configBean 的这个bean 所指定的 类对象 ,就是Config。相当于直接向构造器传入了Config实参。

Spring 在运行的时候,会先创建Bean,所以这个时候,在WangYifei 这个类中的

private Config config;

已经是有引用了,引用的也就是 XML 文件中对id 为wangyifei 的构造器 所传入的Config 类。

这个清晰之后,再看Employee 这个 验证类。

public static void main(String[] args) {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("config.xml");
        WangYifei wangYifei = classPathXmlApplicationContext.getBean(WangYifei.class);
        if (wangYifei.getConfig() != null) {
            wangYifei.getConfig().sayOk();
        }
    }

直接定义 main 方法,开始验证。 Spring 对于 Spring Bean 有一个专门用来管理和协作的组件,这个组件就是 应用上下文 (ApplicationContext) 这个上下文主要分为五个分别是:

1、AnnotationConfigApplicationContext:从一个或多个基于Java配置类中加载Spring 应用上下文。
2、AnnotationConfigWebApplicationContext:从一个或多个基于Java的配置类中加载 Spring Web 的应用上下文。
3、CLassPathXmlApplicationContext:从类路径下的一个或多个XML配置文件中定义,把应用上下文的定义文件作为类资源。
4、FileSystemXmlApplicationContext:从文件系统下的一个或多个XML配置文件中加载应用上下文。
5、XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载应用上下文。

这个列出来之后应该也知道是使用哪一个了,使用 CLassPathXmlApplicationContext 比较方便。从系统中其实也可以,但是把项目换到别的地方就不行了。太固定了。

随后指定一个实例化 ClassPathXmlApplicationContext 并给到xml文件完整名称。读取文件。
读取文件之后或者Bean 对象,使用getBean() 方法,指定Bean。引用给wangyifei 这个变量。
再进行一个判断,如果不是null 说明注入成功了。如果是null,说明注入失败了,这个时候就需要检查文件的地址啊,类写对错没啊,xml文件配置对了没啊,等等等等。
这个时候的wangYifei已经可以相当于 WangYifei wangYifei = new WangYifei(new Config); 进行使用了。
可以相对应的,直接使用 Config 中的sayOk() 方法了。

最后看一下运行结果

"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\IntelliJ IDEA 2019.2.4\lib\idea_rt.jar=52321:D:\IntelliJ IDEA 2019.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;D:\java core 1\spring\target\classes;C:\Users\22150\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.2.4.RELEASE\spring-boot-starter-web-2.2.4.RELEASE.jar;C:\Users\22150\.m2\repository\org\springframework\boot\spring-boot-starter\2.2.4.RELEASE\spring-boot-starter-2.2.4.RELEASE.jar;C:\Users\22150\.m2\repository\org\springframework\boot\spring-boot\2.2.4.RELEASE\spring-boot-2.2.4.RELEASE.jar;C:\Users\22150\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.2.4.RELEASE\spring-boot-autoconfigure-2.2.4.RELEASE.jar;C:\Users\22150\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.2.4.RELEASE\spring-boot-starter-logging-2.2.4.RELEASE.jar;C:\Users\22150\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\22150\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\22150\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.12.1\log4j-to-slf4j-2.12.1.jar;C:\Users\22150\.m2\repository\org\apache\logging\log4j\log4j-api\2.12.1\log4j-api-2.12.1.jar;C:\Users\22150\.m2\repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;C:\Users\22150\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\22150\.m2\repository\org\yaml\snakeyaml\1.25\snakeyaml-1.25.jar;C:\Users\22150\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.2.4.RELEASE\spring-boot-starter-json-2.2.4.RELEASE.jar;C:\Users\22150\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.10.2\jackson-databind-2.10.2.jar;C:\Users\22150\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.10.2\jackson-annotations-2.10.2.jar;C:\Users\22150\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.10.2\jackson-core-2.10.2.jar;C:\Users\22150\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.10.2\jackson-datatype-jdk8-2.10.2.jar;C:\Users\22150\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.10.2\jackson-datatype-jsr310-2.10.2.jar;C:\Users\22150\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.10.2\jackson-module-parameter-names-2.10.2.jar;C:\Users\22150\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.2.4.RELEASE\spring-boot-starter-tomcat-2.2.4.RELEASE.jar;C:\Users\22150\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.30\tomcat-embed-core-9.0.30.jar;C:\Users\22150\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.30\tomcat-embed-el-9.0.30.jar;C:\Users\22150\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.30\tomcat-embed-websocket-9.0.30.jar;C:\Users\22150\.m2\repository\org\springframework\boot\spring-boot-starter-validation\2.2.4.RELEASE\spring-boot-starter-validation-2.2.4.RELEASE.jar;C:\Users\22150\.m2\repository\jakarta\validation\jakarta.validation-api\2.0.2\jakarta.validation-api-2.0.2.jar;C:\Users\22150\.m2\repository\org\hibernate\validator\hibernate-validator\6.0.18.Final\hibernate-validator-6.0.18.Final.jar;C:\Users\22150\.m2\repository\org\jboss\logging\jboss-logging\3.4.1.Final\jboss-logging-3.4.1.Final.jar;C:\Users\22150\.m2\repository\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar;C:\Users\22150\.m2\repository\org\springframework\spring-web\5.2.3.RELEASE\spring-web-5.2.3.RELEASE.jar;C:\Users\22150\.m2\repository\org\springframework\spring-beans\5.2.3.RELEASE\spring-beans-5.2.3.RELEASE.jar;C:\Users\22150\.m2\repository\org\springframework\spring-webmvc\5.2.3.RELEASE\spring-webmvc-5.2.3.RELEASE.jar;C:\Users\22150\.m2\repository\org\springframework\spring-aop\5.2.3.RELEASE\spring-aop-5.2.3.RELEASE.jar;C:\Users\22150\.m2\repository\org\springframework\spring-context\5.2.3.RELEASE\spring-context-5.2.3.RELEASE.jar;C:\Users\22150\.m2\repository\org\springframework\spring-expression\5.2.3.RELEASE\spring-expression-5.2.3.RELEASE.jar;C:\Users\22150\.m2\repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;C:\Users\22150\.m2\repository\org\springframework\spring-core\5.2.3.RELEASE\spring-core-5.2.3.RELEASE.jar;C:\Users\22150\.m2\repository\org\springframework\spring-jcl\5.2.3.RELEASE\spring-jcl-5.2.3.RELEASE.jar" com.core.spring.test.Employee
14:08:02.089 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@21588809
14:08:02.332 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 2 bean definitions from class path resource [config.xml]
14:08:02.381 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'wangyifei'
14:08:02.397 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'configBean'
我注入进来了 -> com.core.spring.test.Config@7113b13f
我注入进来了 -> com.core.spring.test.Config@7113b13f
Hello World!