首页 > 编程语言 >手撕Spring6教程(六)第一个Spring程序的深度剖析

手撕Spring6教程(六)第一个Spring程序的深度剖析

时间:2023-03-14 11:34:20浏览次数:70  
标签:xml 教程 配置文件 构造方法 Spring beans spring org Spring6

第一个Spring程序详细剖析

本篇文章说说Spring的第一个程序详细的剖析,上篇说了spring第一个程序的前期准备工作

​https://blog.51cto.com/u_15485663/6110947​

配合视频教程观看,更易理解吸收,动力节点老杜的Spring6教程采用难度逐步递进的方式,从入门的第一个程序到手写Spring框架,真正的能够让小白成为老手。如果你是老程序员不妨看看手写Spring框架,也会让你受益颇多。

<bean id="userBean" class="com.powernode.spring6.bean.User"/>

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

Object userBean = applicationContext.getBean("userBean");

1. bean标签的id属性可以重复吗?

package com.powernode.spring6.bean;



/**

* @author 动力节点

* @version 1.0

* @className Vip

* @since 1.0

**/

public class Vip {

}

<?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="userBean" class="com.powernode.spring6.bean.User"/>

<bean id="userBean" class="com.powernode.spring6.bean.Vip"/>

</beans>

运行测试程序:

手撕Spring6教程(六)第一个Spring程序的深度剖析_User

 

通过测试得出:在spring的配置文件中id是不能重名。

2. 底层是怎么创建对象的,是通过反射机制调用无参数构造方法吗?

package com.powernode.spring6.bean;



/**

* bean,封装用户信息。

* @author 动力节点

* @version 1.0

* @since 1.0

*/

public class User {

public User() {

System.out.println("User的无参数构造方法执行");

}

}

在User类中添加无参数构造方法,如上。

运行测试程序:

手撕Spring6教程(六)第一个Spring程序的深度剖析_xml_02

通过测试得知:创建对象时确实调用了无参数构造方法。

如果提供一个有参数构造方法,不提供无参数构造方法会怎样呢?

package com.powernode.spring6.bean;



/**

* bean,封装用户信息。

* @author 动力节点

* @version 1.0

* @since 1.0

*/

public class User {

/*public User() {

System.out.println("User的无参数构造方法执行");

}*/



public User(String name){

System.out.println("User的有参数构造方法执行");

}

}

运行测试程序:

手撕Spring6教程(六)第一个Spring程序的深度剖析_spring_03

 

通过测试得知:spring是通过调用类的无参数构造方法来创建对象的,所以要想让spring给你创建对象,必须保证无参数构造方法是存在的。

Spring是如何创建对象的呢?原理是什么?

// dom4j解析beans.xml文件,从中获取class的全限定类名

// 通过反射机制调用无参数构造方法创建对象

Class clazz = Class.forName("com.powernode.spring6.bean.User");

Object obj = clazz.newInstance();

3. 把创建好的对象存储到一个什么样的数据结构当中了呢?

手撕Spring6教程(六)第一个Spring程序的深度剖析_User_04

4. spring配置文件的名字必须叫做beans.xml吗?

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

通过以上的java代码可以看出,这个spring配置文件名字是我们负责提供的,显然spring配置文件的名字是随意的。

5. 像这样的beans.xml文件可以有多个吗?

再创建一个spring配置文件,起名:spring.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="vipBean" class="com.powernode.spring6.bean.Vip"/>

</beans>

package com.powernode.spring6.test;



import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;



public class Spring6Test {



@Test

public void testFirst(){

// 初始化Spring容器上下文(解析beans.xml文件,创建所有的bean对象)

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml","spring.xml");



// 根据id获取bean对象

Object userBean = applicationContext.getBean("userBean");

Object vipBean = applicationContext.getBean("vipBean");



System.out.println(userBean);

System.out.println(vipBean);

}

}

运行测试程序:

手撕Spring6教程(六)第一个Spring程序的深度剖析_spring_05

 

通过测试得知,spring的配置文件可以有多个,在ClassPathXmlApplicationContext构造方法的参数上传递文件路径即可。这是为什么呢?通过源码可以看到:

手撕Spring6教程(六)第一个Spring程序的深度剖析_xml_06

6. 在配置文件中配置的类必须是自定义的吗,可以使用JDK中的类吗,例如:java.util.Date?

<?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="userBean" class="com.powernode.spring6.bean.User"/>

<!--<bean id="userBean" class="com.powernode.spring6.bean.Vip"/>-->



<bean id="dateBean" class="java.util.Date"/>

</beans>

package com.powernode.spring6.test;



import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;



public class Spring6Test {



@Test

public void testFirst(){

// 初始化Spring容器上下文(解析beans.xml文件,创建所有的bean对象)

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml","spring.xml");



// 根据id获取bean对象

Object userBean = applicationContext.getBean("userBean");

Object vipBean = applicationContext.getBean("vipBean");

Object dateBean = applicationContext.getBean("dateBean");



System.out.println(userBean);

System.out.println(vipBean);

System.out.println(dateBean);

}

}

运行测试程序:

手撕Spring6教程(六)第一个Spring程序的深度剖析_xml_07

通过测试得知,在spring配置文件中配置的bean可以任意类,只要这个类不是抽象的,并且提供了无参数构造方法。

7. getBean()方法调用时,如果指定的id不存在会怎样?

运行测试程序:

手撕Spring6教程(六)第一个Spring程序的深度剖析_User_08

通过测试得知,当id不存在的时候,会出现异常。

8. getBean()方法返回的类型是Object,如果访问子类的特有属性和方法时,还需要向下转型,有其它办法可以解决这个问题吗?

User user = applicationContext.getBean("userBean", User.class);

9. ClassPathXmlApplicationContext是从类路径中加载配置文件,如果没有在类路径当中,又应该如何加载配置文件呢?

手撕Spring6教程(六)第一个Spring程序的深度剖析_xml_09

<?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="vipBean2" class="com.powernode.spring6.bean.Vip"/>

</beans>

ApplicationContext applicationContext2 = new FileSystemXmlApplicationContext("d:/spring6.xml");

Vip vip = applicationContext2.getBean("vipBean2", Vip.class);

System.out.println(vip);

没有在类路径中的话,需要使用FileSystemXmlApplicationContext类进行加载配置文件。

这种方式较少用。一般都是将配置文件放到类路径当中,这样可移植性更强。

10. ApplicationContext的超级父接口BeanFactory。

BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring.xml");

Object vipBean = beanFactory.getBean("vipBean");

System.out.println(vipBean);

BeanFactory是Spring容器的超级接口。ApplicationContext是BeanFactory的子接口。

 

 


标签:xml,教程,配置文件,构造方法,Spring,beans,spring,org,Spring6
From: https://blog.51cto.com/u_15485663/6120136

相关文章

  • springboot 中使用@Value 获取配置文件中参数问题
    springboot中使用@Value("${spring.redis.password}")获取配置文件中参数时,如果配置文件中没有相关参数,项目启动时会报错Causedby:java.lang.IllegalArgumentExcep......
  • 博客园美化教程
    博客园美化教程前言:没啥时间写博客,不过最进将博客美化了一遍现在,选了好几款不错的主题,感觉都很喜欢,选择困难症犯了,决定写一个完整详细的教程,将几款博客都试一遍,现在先介......
  • springboot中RestTemplate的用法
    配置RestTemplate用于get请求携带multipart/form-data数据原生的RestTemplate在发送get请求时,无法携带body数据,但是有时候咱们的业务场景需要这样做,所以我们可以对RestTem......
  • 自己动手从零写桌面操作系统GrapeOS系列教程——12.QEMU+GDB调试
    学习操作系统原理最好的方法是自己写一个简单的操作系统。写程序不免需要调试,写不同的程序调试方式也不同。如果做应用软件开发,相应的程序调试方式是建立在有操作系统......
  • spring boot整合knife4j
    文档地址:https://doc.xiaominfo.com/knife4j是为JavaMVC框架集成Swagger生成Api文档的增强解决方案。1.添加依赖操作模块:service-uitl<dependency><groupId>com......
  • spring面试
    spring概述 基本使用    IOC        IOC接口     ......
  • Windows 10安装安卓子系统(WSA)最详细教程
    WSA forWindows10下载地址https://pan.baidu.com/s/15rUmm7UsSSY6BIo2UD9MIQ提取码:c97x 要想在Win10系统中正常运行安卓子系统,首先要保证你爱机的系统是“22H2......
  • Spring 邮件发送
    Spring邮件发送1.主要内容2.JavaMail概述 JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口。JavaMail是由Sun定义的一套收发电子邮件的API,它可以......
  • SpringCloud多模块项目打包报错Unable to find main class
    SpringCloud多模块项目打包报错Unabletofindmainclass彻底解决方法:所有子模块都去掉打包插件代码,在parent模块的pom中加上 <build>    <plugins>   ......
  • <input type="file">的全面教程
    <inputtype="file"><input> elementswith type="file" lettheuserchooseoneormorefilesfromtheirdevicestorage.Oncechosen,thefilescanbeupload......