Spring源码:
反射:
//获取类对象
Class clazz = Class.forName("完全限定名");
Class clazz = 对象.getClass();
Class clazz = 类.class;
//创建实例
clazz.newInstance();
Constructor cons = clazz.getDeclareConstructor();
Object obj = cons.newInstance();
然后会用到BeanFactoryPostProcessor,在BeanFactory中去实例化相关的bean,先进行配置,然后可以使用这个接口去定义它的方法。
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
Spring:
接口——>beanFactory——>实例化bean——>属性注入——>before——>初始化bean(init方法调用)——>after
这里before和after其实就是aop的扩展方法:
看beanPostProcessor接口,有个AbstractAutoProxyCreator类,其中有createProxy方法,里面return了一个getProxy调用后的方法,进去
public Object getProxy(@Nullable ClassLoader classLoader) {
return this.createAopProxy().getProxy(classLoader);
}
这里调用了createAopProxy,进去,又创建了createAopProxy调用的方法的对象,但这个方法是接口的方法,进入其实现类DefaultAopProxyFactory,这里主要就是最后这一行,cglib和jdk动态代理。
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
} else {
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
还是这个AbstractAutoProxyCreator类,里面有
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary方法中有个createProxy()方法,正好就是上面那个方法,因为它是创建代理的。
上面箭头的位置正好就是bean的生命周期了,如果想进一步了解,那么去beanFactory接口看注释
Enviroment包含两个主要部分env和properties,看接口的StandardEnviroment实现类,获取系统的环境和配置.。
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new PropertiesPropertySource("systemProperties", this.getSystemProperties()));
propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", this.getSystemEnvironment()));
}
想了解Spring源码需要了解refresh方法,在AbstractAppliacationContext。refresh中有17个方法。
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.
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.
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();
}
}
}
先进入prepareRefresh(),里面的getEnvironment方法
getEnvironment().validateRequiredProperties();
这里创建了个环境对象
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
this.environment = createEnvironment();
}
return this.environment;
}
第二个方法是obtainFreshBeanFactory,也就是获取beanFactory,点进去有个refreshBeanFactory()方法,再进入它的实现类AbstractRefreshableApplicationContext的refreshBeanFactory方法,如果有工厂就清除重新创建一个;这里要注意DefaultListableBeanFactory方法,然后该配置beanFactory
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
第三个方法prepareBeanFactory,这个时候factory准备完成了,该处理beanFactory的增强信息了,也就是粉色部分,这里最开始的beanFactory赋的都是默认值,现在要填充定义好的属性值。下面这个图只是一个总体功能介绍,不是执行顺序。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
}
上面只是这个方法的一小部分,可以看到有set、add、register、ignore等设置。
第四个方法是postProcessBeanFactory,后置处理bean工厂。
第五个方法是invokeBeanFactoryPostProcessors,调用beanFactory的后置处理器,也就是调用粉色的部分。
第六个方法registerBeanPostProcessors,是注册bean processors
第七个方法initMessageSource,进行国际化处理(i18n),也就是页面语言切换
第八个方法initApplicationEventMulticaster,初始化应用程序事件的多播器,用来后面进行事件的监听
第九个方法onRefresh,没什么意义
第十个方法registerListeners,注册监听器,也就是beanFactory完成之前把监听器,监听事件等都准备好
第十一个方法finishBeanFactoryInitialization,实例化所有非懒加载的单例
1、Spring IOC的理解
两个东西:控制反转和容器,控制反转简单说明即可,容器:存储对象用的,使用map结构来存储对象,在spring中一般存在三级缓存,singletonObject存放完整的bean对象。创建到销毁的过程都是由Spring管理
细化:
- 容器的创建过程(beanFactory、DefaultListableBeanFactory),创建bean工厂,向bean工厂中设置一些参数(BeanPostProcessor,Aware接口的子类)等属性
- 加载解析bean对象,准备好要创建的bean对象的定义对象beanDefinition(xml,注解解析过程)
- 开始beanFactoryPostProcessor的处理,这里是扩展点,(PlaceHolderConfigureSupport,ConfigurationClassPostProcessor)
- beanPostProcessor的注册功能,方便后续对bean对象的扩展功能
- 通过反射的方式将BeanDefinition对象实例化成具体的bean对象
- bean对象的初始化过程(DI,调用Aware子类的方法,调用BeanPostProcessor前置处理方法,调用init方法,调用BeanPostProcessor的后置处理方法)
- 生成完整的bean对象,通过getBean方法可以直接获取到
- 销毁过程
2、Spring IOC的底层实现
反射 + 工厂
createBeanFactory,getBean,doGetBean,createBean,doCreateBean,createBeanInstance,populateBean。
- 先通过createBeanFactory创建一个beanFactory(DefaultListableBeanFactory)
- 开始循环创建对象,容器中的bean默认是单例,所以优先通过getBean,doGetBean从容器中查找,
- 如果找不到的画,通过createBean,doCreateBean方法以反射的方式创建对象,一般情况下使用的是无参构造方法(getDeclaredConstructor、newInstance)创建
- 进行对象的属性填充populateBean
- 进行其他的初始化操作(initializingBean)
3、bean的生命周期
- 实例化:反射的方式生成对象
- 填充属性bean:熟悉可以谈谈populateBean,循环依赖问题(三级缓存)
- 调用aware接口方法:invokeAwareMethod(完成BeanName,BeanFactory,BeanClassLoader对象的属性设置)
- 调用BeanPostProcessor的前置处理方法:使用比较多的由ApplicationContextPostProcessor,设置ApplicationContext,Enviroment,ResourceLoader等对象
- 调用init-method方法:invokeInitmethod()方法,判断是否实现了InitializeingBean接口,如果由调用AfterPropertiesSet方法,没有不调用
- 调用BeanPostProcessor的后置处理方法:使用比较多的Spring aop就是在这里实现的,AbstractAutoProxyCreator就是干这个用的
- 获取到完整的bean,可通过getBean获取对象
- 销毁:判断是否实现了DispoableBean接口,调用destroyMethod方法
4、Spring的循环依赖如何解决?
关键点:三级缓存;提前暴露对象;aop
A依赖B,B依赖A,不断依赖下去;
bean的创建过程是这样的:实例化---初始化(填充属性)
- 先创建A对象,实例化A对象,此时A对象b属性为null,从容器中查找B对象,找到了就赋值,找不到就创建B对象
- 实例化B对象,填充B对象的属性,从容器中查找A对象,找不到创建A对象
- 这里就闭环导致循环依赖的
5、缓存的放置时间和删除时间
三级缓存:createBeanInstance之后放置,addSingletonFactory()方法
二级缓存:第一次从三级缓存确定对象是代理对象还是普通对象的时候,同时删除三级缓存,getSingleton()
一级缓存:将完整对象生成后,放入一级缓存,删除二三级缓存,addSingleton()
6、BeanFactory和FactoryBean有什么区别?
相同点:都是用来创建bean对象的
不同点:当使用beanFactory创建对象的时候必须遵循严格的生命周期流程,比较复杂,如果想要自定义某个对象的创建,同时创建完成的对象交给spring管理,就需要实现FactoryBean接口(BeanFactory是复杂版创建,FactoryBean是简化版创建)
- isSingleton:是否是单例
- getObjectType:获取返回对象的类型
- getObject:自定义创建对象的过程(new、反射、动态代理)
7、常用的设计模式
单例模式、原型模式、工厂模式、模板方法模式(postProcessBeanFactory,onRefresh,initPropertyValue,))、策略模式(xmlBeanDefinitionReader、PropertiesBeanDefinition)、观察者模式(listener、event、multicart)、适配器模式(Adapter)、装饰者模式(BeanWrapper)、责任链模式(使用aop的时候会先生成一个拦截器链)、代理模式(动态代理)、委托者模式(delegate)
8、aop底层实现原理
aop是ioc的一个扩展功能
bean的创建过程中有个步骤可以对bean进行扩展实现,aop本身就是个扩展功能,所以在BeanPostProcessor的后置处理器中来实现
- 代理对象的创建过程(advice、切面、在哪些方法上进行扩展)
- 通过jdk或cglib的方式来生成代理对象
- 在执行方法调用的时候,会调用生成的字节码文件中,直接会找到DynamicAdvisoredInterceptor类的intercept方法,从此方法开始执行
- 根据之前定义好的通知来生成拦截器链
- 从拦截器链中依次获取每一个通知开始进行执行,执行过程中为了方便找到下一个通知是哪个,会有一个InvocationInterceptor对象,找的时候是从-1的位置开始查找,并且执行的
9、Spring事务是如何回滚的
其实是在问spring事务管理是怎么实现的?
Spring的事务是由aop来实现的,首先生成具体的代理对象,按照aop的整套流程完成具体的逻辑操作,一般是这样,但是aop中事务不是通过通知来实现的,而是通过TransactionInterceptor来实现的,然后调用invoke来实现具体的逻辑。
- 准备工作,包含具体的操作:解析各个方法上事务相关的属性,根据具体的属性来判断是否开启新事务
- 当需要开启新事务时,获取数据库连接,关闭自动提交功能,开启事务
- 执行具体的sql逻辑操作
- 在操作过程中,如果执行失败了,那么会通过completeTransactionAfterThrowing来完成事务的回滚操作,回滚的具体逻辑是doRollBack方法来实现的,实现的时候也是要先获取连接对象,通过连接对象回滚
- 如果执行过程中,没有发生意外,通过commitTransactionAfterReturing来完成事务的提交操作,事务的具体逻辑是通过doCommit来实现的,也是先获取连接再提交
- 当事务执行完毕之后需要清除相关的事务信息cleanupTransactionInfo