前言
HelloWorld对于IT行业实属经典,就像一些经典电影,都不曾被超越。
之前的《tiny-SpringIoc学习系列博客》都是对于源码的一些初步分析,
现在要在对于springIoc的理解基础之上,至于实践应用。
系列博客如下:
《step1:tiny Spring IoC学习一》——最基本的容器BeanFactory
《step2:tiny Spring IoC学习二》——将bean创建放入工厂
《step3:tiny-Spring-IoC学习三》——为bean注入属性
《step4:tiny-spring-ioc学习四》——读取xml配置来初始化bean
《step5:tiny-spring-ioc学习五》——ApplicationContext登场引入spring框架之前
先附上一段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(){
System.out.println("HelloWorld concortion ");
}
}
- 在没有引入spring之前,我们先来测试一下创建类的实例,以及方法的调用情况:
Main函数:
public static void main(String[] args){
//第一种方式:实例化类调用方法(和spring无关)
HelloWorld helloWorld=new HelloWorld();
helloWorld.setName("jialimin");
helloWorld.SayHello();
}
代码不再详细解释,直接看执行结果:
总结一句话:第一行代码实例化类,相当于调用类的默认构造函数,所以结果输出:HelloWorld concortion ,然后调用对象的方法赋值并调用SayHello方法输出,便如执行结果显示内容一致。
引入spring容器(前提加入有关spring的jar包)
- 添加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”);
都干了一些什么,有一个进一步的认识与了解。顺便提到反射机制。