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

第一个Spring程序详细剖析

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

跟老杜手撕Spring6教程(五)第一个Spring程序_ewertyucf的博客-CSDN博客

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

相关的学习资料也给大家备好了

https://www.bilibili.com/video/BV1Ft4y1g7Fb/

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

运行测试程序:

通过测试得出:在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类中添加无参数构造方法,如上。

运行测试程序:

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

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

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的有参数构造方法执行");

    }

}

运行测试程序:

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

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

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

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

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

Object obj = clazz.newInstance();

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

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);

    }

}

运行测试程序:

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

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);

    }

}

运行测试程序:

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

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

运行测试程序:

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

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

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

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

<?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的子接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值