《Spring实践——不一样的'HelloWorld'》

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012788601/article/details/73433950
package com.dynamic.study1;

public class HelloWorld {

    private String name;

    public void setName(String name) {
        System.out.println("HelloWorld class's name is set value"+name);
        this.name = name;
    }

    public void SayHello(){
        System.out.println("hello "+ name);
    }

    public HelloWorld(){
        System.out.println("HelloWorld concortion ");
    }

}
  1. 在没有引入spring之前,我们先来测试一下创建类的实例,以及方法的调用情况:
    Main函数:
public static void main(String[] args){

    //第一种方式:实例化类调用方法(和spring无关)
    HelloWorld helloWorld=new HelloWorld();
    helloWorld.setName("jialimin");
    helloWorld.SayHello();
}

代码不再详细解释,直接看执行结果:
这里写图片描述

总结一句话:第一行代码实例化类,相当于调用类的默认构造函数,所以结果输出:HelloWorld concortion ,然后调用对象的方法赋值并调用SayHello方法输出,便如执行结果显示内容一致。

  • 引入spring容器(前提加入有关spring的jar包)

    1. 添加spring配置文件applicationContext.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="helloWorld" class="com.dynamic.study1.HelloWorld">
        <property name="name" value="jimmy"></property>
    </bean>
</beans>

2· Main函数:

    public static void main(String[] args){

        //使用xml获取bean方式
        ApplicationContext atx= new ClassPathXmlApplicationContext("applicationContext.xml");
            HelloWorld helloWorld = (HelloWorld)atx.getBean("helloWorld");
            helloWorld.SayHello();
    }

此时执行main主函数,大家可以先思考一下,看看代码的执行结果…….
看控制台:
这里写图片描述

  • 对比

和没有引入spring之前,除了多了一些spring日志输出以外,别的貌似没有什么变化,那接下来该行代码,会有什么样的执行结果?

public static void main(String[] args){

    //使用xml获取bean方式
    ApplicationContext atx= new ClassPathXmlApplicationContext("applicationContext.xml");
}

大家可以先来思考一下:执行结果会是什么呢????
这里写图片描述

不知道和你们想象的结果一致,现简单说明一下,在解析xml文件的时候,会通过反射机制将配置的bean实例化。在这篇博客《step4:tiny-spring-ioc学习四》——读取xml配置来初始化bean中,提到,xml解析和我们直接new实例化对象的区别,就是通过类的全路径来动态加载类,并通过调用class对象的newInstance方法来实例化。在初始化该类的过程中,会先执行类的默认构造函数,如果无参构造函数显示声明,则会调用显示调用该函数,配置文件中的属性赋值也会在初始化过程中给予赋值,所以,HelloWorld对象的name属性会被赋值,so,就如结果看到的。
这里,大家来思考一个问题:如果helloWorld类中显示声明了一个带有参数的构造函数,(没有无参的构造函数),结果会怎样?
HelloWorld类:

package com.dynamic.study1;

public class HelloWorld {
    private String name;
    public void setName(String name) {
        System.out.println("HelloWorld class's name is set value "+name);
        this.name = name;
    }
    public void SayHello(){
        System.out.println("hello "+ name);
    }
    public HelloWorld(String name){
        System.out.println("HelloWorld concortion "+name);
    }
}

执行结果:
这里写图片描述

对,是的,报错了,为什么?
通过错误能分析出:没有默认的构造函数被发现,所以,映射出一个问题:java反射和默认的构造函数有什么关系?
当时傻,没有反应过来,等到后来明白以后,才发现如此简单……
通过反射生成对象主要有两种方式,这里通过使用class对象的newInstance()方法来创建Class对象对应类的实例。所以,就得看newInstance()方法都做了什么?才能找到问题的根源:
看官方文档:
这里写图片描述

可以看到,如果该类没有null构造方法,就会报初始化失败的错误,正如上文的错误。再分析,为什么没有null的构造方法就会初始化失败?
其实这种反射方式的根本来源还是通过new的实例化对象,所以,想想,这行代码都干了什么?
HelloWorld helloWorld=new HelloWorld();
显然,这行代码不就调用没有参数的构造函数了嘛!!所以,一步步分析就发现了问题的根源。
说了这么多,只是想让大家对于这行代码:
ApplicationContext atx= new ClassPathXmlApplicationContext(“applicationContext.xml”);
都干了一些什么,有一个进一步的认识与了解。顺便提到反射机制。

猜你喜欢

转载自blog.csdn.net/u012788601/article/details/73433950