Spring源码学习(一)ClassPathXmlApplicationContext 1.2 obtainFreshBeanFactory() 设计模式的理解

前言:这里是记录我自己学习spring源码的知识理解,有什么问题大家可以批评我!首先大家看一下gif源码动态跳转图,可能不太理解他为什么这么跳来跳去,甚至觉得有点晕乎乎的。现在我用简单的demo例子去解释为什么这么设计代码,理解之后会觉得他这个设计特别的好。首先我们先从自己的MyTest.java中选中ClassPathXmlApplicationContext("spring.xml");这一行往里面跳转。ClassPathXmlApplicationContext applicati
摘要由CSDN通过智能技术生成

前言:

这里是记录我自己学习spring源码的知识理解,将难变成简单的过程,小demo更容易让人理解,有什么问题大家可以批评我!

首先大家看一下gif源码动态跳转图,可能不太理解他为什么这么跳来跳去,甚至觉得有点晕乎乎的。现在我用简单的demo例子去解释为什么这么设计代码,理解之后会觉得他这个设计特别的好。

首先我们先从自己的MyTest.java中选中ClassPathXmlApplicationContext("spring.xml");这一行往里面跳转。

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");

发现走到了this这里,this关键字的一些理解(推荐1推荐2

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
   this(new String[] {configLocation}, true, null);// Coco 知识点:this关键字在java中的使用,在jvm中运行图。
}

...

refresh(); // 点击this调用本类构造器走到refresh()方法里面

重点来了

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 这句代码写的特别好,知识点接口、抽象类、抽象方法、模板模式、implement和abstract的区别
@Override
	public void refresh() throws BeansException, IllegalStateException {
		...
			// obtainFreshBeanFactory 负责xml解析并且封装成对象,叫beandefinition
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Coco 知识点:接口、抽象类、重写 思考:beanFactory为什么返回的是一个接口?写的特别好!!

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);
 ...

从上面的代码我们可以知道ConfigurableListableBeanFactory.java是一个接口,接口不能被实例化所以我们又想调用到这个类中的方法,只能在本类中构造一个方法,当然方法也不能return 一个对象,所以必须是abstract 方法,而子类可以extend(不能implement)本类这样扩展性就来了。

1、obtainFreshBeanFactory(); 可以被其他子类具体实现(模板模式)

2、ConfigurableListableBeanFactory 是一个接口,所以可以被多个类实现,具体调用哪个类的接口又可以具体类调用!

以下是是将上面的 ConfigurableListableBeanFactory.java  obtainFreshBeanFactory();抽象方法和  ConfigurableListableBeanFactory.java 的实现三者之间关系的小demo。

/**
 * 我们清楚接口是不可以被实例化, 但是接口引用可以指向1个实现该接口的对象。也就是说.假如类A impletments 了接口B 那么下面是合法的:
 * <p>
 * B b = new A();
 */
public interface interfaceDemo1 {

    void 我是框架方法大家都来实现我呀();
}

package com.enjoy.jack.coco;


public abstract class interfaceDemo2 {


    // interface 通常使用是用 @autowired注解 注入使用,但是也可以通过new的方式去使用,但是接口是不可以被实例化的,编译就不通过了
    // 所以用本类中的方法去实现 getInterfaceDemo1() 返回 interfaceDemo1 实体对象,同时也不可以 return new interfaceDemo1(),
    // 对象不可以被实例化,所以只能定义一个abstract方法,而定义了一个abstract方法类要求必须是abstract

    // 抽象类是抽象类,接口是接口
    // 抽象类是类的一种,关键字是class,只不过用abstract关键字修饰了就是抽象类
    // 接口的关键字是interface,和class是同一个层次的。
    // 至于抽象类和接口的区别,你可以在网上搜一搜。
    // 简单总结就是:
    // 相同点:
    //         1. 具体子类都需要实现他们的抽象方法
    //         2. 都不能被实例化
    // 不同点:
    //          1. 接口中只能定义抽象方法和常量,可多重实现
    //          2. 抽象方法中可以定义任何的类型,只能单重继承

    // 总结:

    /**
     * 1、abstract方法必须在abstract类中
     *
     * 2、A a1 = getA();
     * 1)A是一个接口,不能通过new的方式实现,所以实例化A.java需要在C.java中定义一个抽象方法(return new 不行所以必须是abstract方法)。
     * 2)getA()是抽象方法,要求getA()本类是抽象类
     * 3)a1只能调用接口定义的方法
     * 4)D.java实现了接口,D d = (D) a1; d对象才可以调用自己的方法包含实现的重写方法
     *
     * 5) 重点!!! getA()是抽象方法,可以由子类实现,所以可以用到模板模式
     *
     * 所以好像什么都写了,实际上什么都没写,延展性特别好
     */
    public void test() {
        // new 方式 不被允许
        // interfaceDemo1 interfaceDemo1 = new interfaceDemo1();
        interfaceDemo1 demo1 = getInterfaceDemo1();
        // 通过抽象方法的方式来获取对象和对象的方法
        demo1.我是框架方法大家都来实现我呀();
        // demo1.self() 错误 demo1只能调用的是interfaceDemo1接口定义的方法,需要调用哪个强转哪个
        interfaceDemo1的具体实现 d = (interfaceDemo1的具体实现) demo1;
        d.self();
    }

    public abstract interfaceDemo1 getInterfaceDemo1();
}
package com.enjoy.jack.coco;

public class interfaceDemo1的具体实现 implements interfaceDemo1 {
    @Override
    public void 我是框架方法大家都来实现我呀() {
        System.out.println("interfaceDemo1的具体实现 重写方法.....");
    }

    public void self() {
        System.out.println("dajiahao !!!");
    }
}
/**
 * 如果将一个类设置为abstract,则此类必须被继承使用。此类不可生成对象,必须被继承使用。 博客:https://blog.csdn.net/Sicily_winner/article/details/120377175
 * <p>
 * 当abstract用于修饰方法时,此时该方法为抽象方法,此时方法不需要实现,实现留给子类覆盖,子类覆盖该方法之后方法才能够生效。
 */
// public class interfaceDemo2模板模式1 implements interfaceDemo2{// 错误必须是extend
public class interfaceDemo2模板模式1 extends interfaceDemo2 {// 错误必须是extend

    @Override
    public interfaceDemo1 getInterfaceDemo1() {
        System.out.println("爸爸你被我覆盖啦,我是模板模式1");
        return null;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值