- 一、spring IOC执行步骤
- 二、spring Aop
- 三、要点
- 1、加载xml文件
- 2、ClassPathXmlApplicationContext方法
- 3、refresh方法
- 4、prepareRefresh()创建前的预处理
- 5、obtainFreshBeanFactory()获取BeanFactory
- 7、postProcessBeanFactory(beanFactory)后置处理
- 8、invokeBeanFactoryPostProcessors(beanFactory)
- 9、registerBeanPostProcessors(beanFactory)
- 10、initMessageSource()
- 11、initApplicationEventMulticaster()
- 12、onRefresh()
- 13、registerListeners()
- 14、finishBeanFactoryInitialization(beanFactory)
- 15、finishRefresh()
一、spring IOC执行步骤
1、加载配置文件
使用BeanDefinitionReader加载 spring.xml(或注解方式、配置类、其他方式)配置文件,将其中的
2、配置文件增加扩展
使用 BeanFactoryPostProcessor 对xml配置类进行自定义拓展,如 修改bean等
3、创建BeanFactory(IOC容器)
也就是IOC容器或对象工厂;在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。
由 beanFactory 创建每个类对应的单例对象, 利用了反射根据类名创建每个类的实例对象(构造,初始化方法)
4、bean实例化
初始化bean对象中:BeanPostProcessor .before 前置增加 和 BeanPostProcessor .after 后置增强
5、Demo示例
本文源码分析基于Spring5.0.0,所以pom文件中引入5.0的依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
</dependencies>
然后写一个简单的接口和实现类 ```java public interface IOCService { public String hollo(); }
public class IOCServiceImpl implements IOCService { public String hollo() { return “Hello,IOC”; } }
- 新建一个application-ioc.xml
```java
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">
<bean id="iocservice" class="cn.shiyujun.service.impl.IOCServiceImpl"/>
</beans>
- 启动Spring
public class IOCDemo {
public static void main (String args[]){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application-ioc.xml");
IOCService iocService=context.getBean(IOCService.class);
System.out.println(iocService.hollo());
}
}
二、spring Aop
1、底层原理
实际上为bean 创建一个proxy(代理:JDKproxy 或者CGLIBproxy),然后在调用bean方法时,会通过proxy来调用bean方法。
重点过程可分为:
1)通过AspectJAutoProxyBeanDefinitionParser类将AnnotationAwareAspectJAutoProxyCreator注册到Spring容器中
2)AnnotationAwareAspectJAutoProxyCreator类的postProcessAfterInitialization()方法将所有有advice的bean重新包装成proxy
3)调用bean方法时通过proxy来调用,proxy依次调用增强器的相关方法,来实现方法切入
2、Demo 示例
引入maven依赖(笔者使用SpringBoot开发)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
创建接口及其实现类
public interface Person {
void say();
}
public class Student implements Person{
public void say(){
System.out.println("这是一个苦逼的程序员");
}
}
创建切面类
@Aspect
public class AspectJTest {
@Pointcut("execution(* *.say(..))")
public void test(){}
@Before("test()")
public void before(){
System.out.println("before test..");
}
@After("test()")
public void after(){
System.out.println("after test..");
}
@Around("test()")
public Object around(ProceedingJoinPoint p){
System.out.println("before1");
Object o = null;
try {
o = p.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("after1");
return o;
}
}
创建beans.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:aspectj-autoproxy/>
<bean id="student" class="test.Student"/>
<bean class="test.AspectJTest"/>
</beans>
测试类 ```java public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
Person bean2 = (Person)ac.getBean("student");
bean2.say();
}
运行结果:
```java
// 结果如下:
before1
before test..
这是一个苦逼的程序员
after1
after test..
总结:AOP功能的使用还是比较简单的,把相关bean注入到Spring容器中,编写好相应的Aspect类即可
三、要点
1、加载xml文件
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application-ioc.xml");
2、ClassPathXmlApplicationContext方法
3、refresh方法
BeanFactory创建的主要流程都在里面
//准备为此上下文以进行刷新
prepareRefresh();
// 告诉子类刷新内部bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//准备在目前情况下使用的bean工厂(BeanFactory的预准备工作)
prepareBeanFactory(beanFactory);
try {
//允许在上下文子类中对bean工厂进行后处理
postProcessBeanFactory(beanFactory);
//调用在上下文中注册的bean的工厂处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截Bean创建的Bean处理器
registerBeanPostProcessors(beanFactory);
// 为此上下文初始化消息源
initMessageSource();
//为此上下文初始化事件多播器
initApplicationEventMulticaster();
// 在特定上下文子类中初始化其他特殊bean(空方法,留给子类重写使用的方法,在SpringBoot中,会将该方法重写,并且在该方法中创建了嵌入式Servlet容器实例)
onRefresh();
// 检查侦听器bean并注册它们
registerListeners();
// 实例化所有剩余的(非延迟)单例
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应的事件
finishRefresh();
}
4、prepareRefresh()创建前的预处理
在该方法中会有以下主要方法:
//在上下文环境中初始化任何占位符属性源(空方法)
initPropertySources();
//验证标记为必需的所有属性都是可解析的
getEnvironment().validateRequiredProperties();
//允许收集早期的ApplicationEvent,一旦多播器可用时就发布
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
initPropertySources()初始化一些占位符属性源设置,子类可以自定义个性化的属性设置;
getEnvironment().validateRequiredProperties()验证所有属性标注都是可解析的;
earlyApplicationEvents = new LinkedHashSet()保存容器中的一些早期的事件,在有了多播器后就可以被直接发布(目前我们没有设置事件,因此为null);
5、obtainFreshBeanFactory()获取BeanFactory
- refreshBeanFactory刷新(创建)BeanFactory,并创建了beanFactory = new DefaultListableBeanFactory();
- getBeanFactory()方法,返回刚刚在1中创建的BeanFactory对象;
```java
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
}refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
<a name="CMjIK"></a>
#### 6、prepareBeanFactory(beanFactory)预准备工作
BeanFactory的预准备工作(BeanFactory进行一些设置),配置工厂的标准上下文(容器)特征,例如上下文的ClassLoader和后处理器:
```java
将上一步获取的BeanFactory对象传入进来进行配置
@param beanFactory the BeanFactory to configure
7、postProcessBeanFactory(beanFactory)后置处理
postProcessBeanFactory(beanFactory)该方法也是一个空方法,是为子类所留,子类通过重写该方法,可以在BeanFactory创建并预准备完成以后做进一步的设置; 这里也就是编写后置处理方法的地方;
8、invokeBeanFactoryPostProcessors(beanFactory)
该方法必须在单例实例化之前被调用;一些后置处理器的执行是会按照优先级(PriorityOrdered接口)和顺序(Ordered接口)依次执行的,最后执行没有实现任何优先级或顺序接口的BeanDefinitionRegistryPostProcessor(后置处理器)方法;
9、registerBeanPostProcessors(beanFactory)
会获取所有的BeanPostProcessor(内部bean,非我们创建的)(后置处理器默认都可以通过PriorityOrdered,Ordered接口指定优先级);
先注册(加入到beanFactory中)PriorityOrdered优先级接口的BeanPostProcessor;接着就是实现了Ordered接口,最后还是执行没有实现任何优先级或顺序接口的BeanPostProcessor;
10、initMessageSource()
初始化MessageSource组件(国际化功能,消息绑定,消息解析);
- 【MessageSource能取出国际化配置文件中的某个key值,能按照区域信息获取】
- 获取BeanFactory;ConfigurableListableBeanFactory beanFactory = getBeanFactory();
- 判断容器中是否有id为MessageSource组件,如果有该组件,就直接赋值给它,如果没有就创建一个DelegatingMessageSource组件;
- 然后把注册好的MessageSource注册在beanFactory中;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)
11、initApplicationEventMulticaster()
初始化事件派发器:
- 获取beanFactory;
- 从beanFactory获取applicationEventMulticaster的ApplicationEventMulticaster;
- 如果没有用户未配置,就会创建一个SimpleApplicationEventMulticaster事件派发器,并将其注册到beanFactory中,以后其它组件就可以自动注入;
12、onRefresh()
留给子容器(子类),在特定子类中初始化其他特殊的bean;SpringBoot中该方法创建了嵌入式servlet容器的实例;
13、registerListeners()
给容器中将所有项目里面的ApplicationListener注册进来,
Bean的创建
14、finishBeanFactoryInitialization(beanFactory)
初始化所有剩余的(非延迟)单例(在该方法中会创建出来我们所定义出来的bean实例);
- 1、调用beanFactory.preInstantiateSingletons();初始化所有剩余的(非延迟)单例,在这个方法中会对bean进行复杂的判断与创建,会获取bean的定义信息,判断bean是否是实现了FactoryBean的Bean等等;
2、若不是实现了FactoryBean的Bean,就会调用 getBean(beanName)继续创建bean实例; ```java public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// 依次注册新的bean定义
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// 开始所有非懒加载单例bean的初始化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//判断Bean不是抽象的,是单实例的并且不是懒加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断是否是FactoryBean(工厂Bean)的(判断是否实现了FactoryBean的Bean)
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
//如果不是FactoryBean,就会利用getBean(beanName)创建对象
else {
getBean(beanName);
}
}
}
// 触发所有合适的bean的初始化后的回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
- **3、在getBean方法中调用doGetBean(name, null, null, false)方法:先获取缓存(存在一级,二级和三级缓存)中保存的单实例Bean;如果能够获取到,说明之前已经被创建过(创建的单实例Bean都会被缓存起来);若获取不到就继续创建;**
```java
// 检查单例缓存中是否有注册的单实例bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
- 4、在缓存中如果没有,说明是没有创建的bean,就会调用createBean(beanName, mbd, args)来继续创建;
```java
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
//创建Bean实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
5、在createBean方法中的中会有resolveBeforeInstantiation(beanName,mbd)方法,该方法会给bean的后置处理器一个返回代理对象而不是目标bean实例的机会;让BeanPostProcessor先拦截返回代理对象:
- InstantiationAwareBeanPostProcessor的执行;
- 先执行postProcessBeforeInstantiation(beanClass, beanName)方法,如果有返回值再去执行postProcessAfterInitialization(result, beanName)方法;
[<br />](https://blog.csdn.net/qq_43816409/article/details/105922639)
```java
//使用实例化之前的后处理器,以解决指定bean实例化之前是否存在的快捷方式
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//前置实例化处理
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//后置实例化处理
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
6、如果上一步没有返回代理对象时,就会调用如下方法继续创建:
Object beanInstance = doCreateBean(beanName, mbdToUse, args);/创建Bean
doGetBean方法:
在doGetBean方法中调用createBean,然后再createBean中再调用doCreateBean方法;
1、在doCreateBean方法中创建Bean的实例:createBeanInstance(beanName, mbd, args);利用工厂方法或确定对象的构造器创建出Bean实例;
2、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName),允许Bean的后置处理器来修改bean的定义;
3、populateBean(beanName, mbd, instanceWrapper)开始给Bean属性进行赋值:
赋值之前:
获取到InstantiationAwareBeanPostProcessor后置处理器,执行postProcessAfterInstantiation方法;
再获取到InstantiationAwareBeanPostProcessor后置处理器,执行postProcessPropertyValues方法;
赋值:
应用Bean的属性值,为属性利用setter方法进行赋值:applyPropertyValues(beanName, mbd, bw, pvs);
Bean初始化:initializeBean(beanName, exposedObject, mbd):
1、执行Aware接口的方法】执行invokeAwareMethods(beanName, bean)方法,也就是执行BeanNameAware、BeanClassLoaderAware和BeanFactoryAware方法(xxxAware方法);
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
2、执行后置处理器初始化之前的方法(预初始化方法)】调用applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)方法,然后再调用BeanPostProcessor.postProcessBeforeInitialization(result, beanName)方法;
3、【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd):
判断是否是InitializingBean接口的实现,执行接口规定的初始化;
判断是否自定义初始化方法,如果有就执行;
4、【执行后置处理器初始化后方法】applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName),然后执行beanProcessor.postProcessAfterInitialization(result, beanName)方法;
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
//执行Aware接口的方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//【执行后置处理器初始化之前的方法(预初始化方法)】
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//【执行初始化方法】
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//【执行后置处理器初始化后方法】
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
5.在上述的doCreateBean方法返回创建好的exposedObject(bean实例),最终在doGetBean中会返回创建的bean:
6、在doCreateBean方法中注册Bean的销毁方法(不是执行)registerDisposableBeanIfNecessary(beanName, bean, mbd);
将创建的Bean实例添加到缓存( Map
15、finishRefresh()
完成BeanFactory的初始化创建工作,IOC容器就会创建完毕:
- initLifecycleProcessor(),初始化和声明周期有关的处理器;
- getLifecycleProcessor().onRefresh(),获取到之前定义的生命周期处理器(BeanFactory),回调onRefresh方法;
- publishEvent(new ContextRefreshedEvent(this)),发布容器刷新完成事件;
- LiveBeansView.registerApplicationContext(this)。