你怎么理解Spring
IOC、AOP,体现在Spring FrameWork中
只实现IOC功能的花不用导入core依赖,context就行
idea打开的源码都是反编译过的,同时做一个优化,但是只是只读文件,不能操作修改
虽然我们只依赖context,maven帮我们把aop、jcl、beans、core等都下下来了
使用idea和gradle编译spring5源码
spring用gradel开发,
build成功后
新建module
新建一个测试类
package com.suntong.test;
import com.suntong.app.Appconfig;
import com.suntong.service.CityService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
/*
*
* 把类扫描出来 - 扫描出来干什么
* 把bean实例化
* */
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext(Appconfig.class);
System.out.println(annotationConfigApplicationContext.getBean(CityService.class));
}
}
点开AnnotationConfigApplicationContext实现
public AnnotationConfigApplicationContext(Class>... componentClasses) {
//有父类,先调用父类的构造方法,然后调用自己的构造方法
//在自己的构造方法中初始一个读取器和扫描器
this();
register(componentClasses);
refresh();
}
注解配置spring环境
ps:ClassPathXmlApplicationContext 通过xml配置初始化spring环境
无参构造方法
public AnnotationConfigApplicationContext() {
/*
* 父类的构造方法
* 创建一个读取注解等我Bean定义读取器
* 什么是bean定义? BeanDefinition
* */
this.reader = new AnnotatedBeanDefinitionReader(this);
/*
* 可以用来扫描包或类,进而转换成bd
* 但是实际上扫描包工作不是scanner这个对象完成的
* 是spring自己new的一个ClassPathBeanDefinitionScanner
* 这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext
* */
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
但是,该类继承父类,调用父类的无参构造函数
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
点进去GenericApplicationContext
//核心,spring工厂
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
DefaultListableBeanFactory类继承关系复杂,可以理解为其为spring工厂
回到AnnotationConfigApplicationContext类
public AnnotationConfigApplicationContext(Class>... componentClasses) {
//有父类,先调用父类的构造方法,然后调用自己的构造方法
//在自己的构造方法中初始一个读取器和扫描器
//beanFactory
this();
//ac.register(AppConfig.class)
//this.beanDefinitionMap.put(beanName,beanDefinition);
register(componentClasses);
//SpringFramework最重要的方法
refresh();
}
点开refresh方法,里面调用了12个方法
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//重要方法 完成了把类扫描出来 处理各种 import,如 @ImportResource("xxx.xml")
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//new 一个扫描对象 单例
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
spring环境:spring所有组件一起工作保持spring正常运行叫做spring环境,组件如BeanDefinition(用来描述类,描述springbean,因为正常的类存不下那么多信息) , Map , 单例池
扫描:
找到符合规则的类
for循环的到它们的信息,如是否为抽象类,是否为单例,描述等等
最后将其放在map中
调用了invoke方法后扫描之后会实现BeanFactoryPostProcessor接口的实现类
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
这个实现类我们可以自己提供
ctrl + alt + b 看实现类
spring beanFactory和factoryBean有什么区别
factoryBean是特殊bean,去实现一个接口
factoryBean 和 普通bean有什么区别
spring容器是BeanDefinition、BeanFactoryPostProcessor、BeanFactory、BeanDefinition Map以及singletonObjects
单例池concurrentmap
循环依赖:A依赖B,B依赖A
Spring先把B创建出来,new出来时不能把B称之为bean,只是一个对象(bean有完整的spring生命周期,如还要加AOP,lifeclycallback生命周期回调方法,自动注入;)
getSingleton(beanName)方法,第一次get发现A是空,判断原型、判断父子、判断依赖,可以了就记录为正在创建当中,然后就会new B去,然后就是第二次new A的过程,因为B依赖于A,这次get发现A在创建过程中,表示A已经成为了一个对象,就不从单例池中去拿,这样B就创建成功了(涉及到自动装配等很多东西)
bean单例支持,原型不支持循环依赖,可以用lookup函数
spring后置处理器BeanPostProcessor是分功能的,所有后置处理器都继承了这个处理器