前言:
这里是记录我自己学习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;
}
}