Spring容器源码阅读笔记 源码阅读参考

目录

Spring 容器

一. 组件注册

1. 给容器中注册组件

1.1 包扫描:

  • @ComponentScan(value = ?): value里放包扫描的路径。
  • @ComponentScans: 可以配置多个扫描的包
  • excludeFilters=Filter[ ]:指定扫描包的时候按照什么规则排除哪些组件
@ComponentScan(value = "top.nnzi",excludeFilters = {
    
    
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {
    
    Controller.class}),//按照注解排除
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {
    
    UserMapper.class}),//按照类型排除
        @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {
    
    })//自定义排除规则 class里是自定义排除规则的类,实现TypeFilter接口
})
  • includeFilters=Filter[ ]:指定扫描包的时候要包含哪些组件,需将useDefaultFilters置false,使用和excludeFilters相似
@ComponentScan(value = "top.nnzi",includeFilters = {
    
    
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {
    
    Controller.class})
},useDefaultFilters = false)

1.2 容器中注册组件

  • @Component、@Service、@Controller、@Repository、@Configuration 标注的类,主要是自己写的类
  • @Bean:主要导入第三方的包里面的组件
  • @Import:快速给容器中导入一个组件
    1. Import(类名):容器中就会自动注册这个组件,id默认是组件的全名
    2. ImportSelector:将返回值的类导入到容器
    3. ImportBeanDefinitionRegistrar:手动注册bean
@Import(MyImportSelector.class)
//MyImportSelector类实现ImportSelector接口,
//返回需要导入的组件的全类名的数组
public class MyImportSelector implements ImportSelector {
    
    
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    
    
        return new String[]{
    
    "top.nnzi.bean.User"};
    }
}
  • @Conditional({MyCondition.class}):标注在bean上,按照一定的条件判断,满足条件给容器中注册bean。
public class MyCondition implements Condition {
    
    

    /**
     *
     * @param context 判断条件能使用的上下文(环境)
     * @param metadata 注解信息
     * @return true为允许注册,false反之
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    
    
        //获取ioc使用的beanFactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //获取类加载器
        ClassLoader classLoader = context.getClassLoader();
        //获取当前环境信息
        Environment environment = context.getEnvironment();
        //获取bean定义的注册类
        BeanDefinitionRegistry registry = context.getRegistry();
        
        //逻辑代码编写,返回判断值.

        return false;
    }
}
  • 使用Spring提供的FactoryBean(工厂bean):spring用来生产Bean到spring容器中。FactoryBean 通常是用来创建比较复杂的bean,一般的bean 直接用注解即可,但如果一个bean的创建过程中涉及到很多其他的bean 和复杂的逻辑,这时可以考虑用FactoryBean,很多开源项目在集成Spring 时都使用到FactoryBean
    1. 默认获取到的是工厂bean调用getObject创建的对象
    2. 要获取到工厂bean本身,需要给id前面加个&标识
public class UserFactoryBean implements FactoryBean<User> {
    
    

    /**
     *
     * @return 返回一个对象,该对象会被添加到容器
     * @throws Exception
     */
    @Override
    public User getObject() throws Exception {
    
    
        return new User();
    }

    /**
     *
     * @return 返回对象的类型
     */
    @Override
    public Class<?> getObjectType() {
    
    
        return User.class;
    }

    /**
     *
     * @return 是否为单实例创建 true表示单实例
     */
    @Override
    public boolean isSingleton() {
    
    
        return false;
    }
}
  • @Scope():设置组件作用域
    1. prototype:多实例, ioc容器启动并不会去调用方法创建对象在容器中,而是每次获取时才会调用方法创建对象。
    2. singleton:单实例(默认值), ioc容器启动会调用方法创建对象放到ioc容器中,以后每次获取就是从容器中拿
  • @Lazy:bean懒加载,不是在ioc容器启动的时候创建bean,而是当bean获取的时候创建

二. 生命周期

1. bean的生命周期

1.1 bean创建–初始化–销毁的过程:

  • bean创建:
    单实例:在容器启动时创建
    多实例:每次获取时创建
  • bean初始化:成员变量赋值,各种增强等,对象创建完成,并赋值好,调用初始化方法
  • bean销毁
    单实例:关闭容器时
    多实例:容器不会管理这个bean,容器不会调用销毁方法

1.2 可以自定义初始化和销毁方法,容器在bean进行到当前声明周期的时候来调用我们自定义的初始化和销毁方法。

  • 通过@Bean 指定init-method和destroy-method

  • 通过让bean实现InitializingBean接口(定义初始化逻辑):在beanFactory将所有属性设置完成以后调用

  • 在这里插入图片描述

  • 通过让bean实现DisposableBean接口(定义销毁逻辑):在beanFactory销毁单实例对象前调用

  • 在这里插入图片描述

  • 可以使用JSR250注解:标注在方法上。
    1、@PostConstructor:在bean创建完成并且属性赋值完成,来执行初始化方法
    2、@PreDestroy:在容器销毁bean之前通知我们进行清理工作

  • BeanPostProcessor【接口】:bean的后置处理器:在bean初始化前后进行一些处理工作
    (1) postProcessBeforeInitialization:在初始化之前进行一些工作
    (2)postProcessAfterInitialization:在初始化之后进行一些工作

	public interface BeanPostProcessor {
    
    
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    
    
		return bean;
	}
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    
    
		return bean;
	}
}
  • BeanPostProcessor的大致执行流程:

在这里插入图片描述

在这里插入图片描述

  • Spring底层对BeanPostProcess接口的使用
    (1)BeanValidationPostProcessor用来实现数据校验
    (2)AutowireAnnotationBeanPostProcessor,@Autowire实现
    (3)ApplicationContextProcessor将容器注入到bean中
    (4)InitDestroyAnnotationBeanPostProcessor会对@PostConstructor和@PreDestroy注解进行解析来达到容器的初始化和销毁方法的执行等等…

2.自动装配

  • @AutoWired:自动注入【Spring定义的】:可以标注在构造器,参数,方法,属性
  • Spring还支持使用@Resource(JSR250)和@Inject(JSR330)【java规范】
  • 自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx)自定义组件需要实现xxxAware接口;在创建对象的时候会调用接口规定的方法注入相关组件,把Spring底层的一些组件注入到自定义的bean中,xxxAware的功能都是使用xxxAwareProcessor处理的,判断实现了哪个Aware接口然后将bean转化为该类型调用set方法,将容器底层组件注入。
@Override
	@Nullable
	public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    
    
		AccessControlContext acc = null;

		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
    
    
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
    
    
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    
    
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
    
    
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	private void invokeAwareInterfaces(Object bean) {
    
    
		if (bean instanceof Aware) {
    
    
			if (bean instanceof EnvironmentAware) {
    
    
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
    
    
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
			}
			if (bean instanceof ResourceLoaderAware) {
    
    
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
    
    
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
    
    
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			if (bean instanceof ApplicationContextAware) {
    
    
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}

  • @Profile:Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能。
    (1)加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中,默认是default环境。
    (2)写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能生效
    (3)没有标注环境标识的bean在任何环境下都加载
    运行时如何制定环境
    (1)命令行参数,通过在虚拟机参数位置指定-Dspring.profiles.active=xxx来指定运行环境,标注了该环境的bean会被配置进容器中
    (2)程序内指定:创建一个applicationContext ——》设置需要激活的环境,applicationContext.getEnvironment().setActiveProfiles("") ——》注册主配置类,applicationContext.register(xxx.class) ——》启动刷新容器,applicationContext.refresh();

四. AOP

AOP:【动态代理】:指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程模式

4.1 AOP的使用:

  1. 导入aop模块:spring-aspects
  2. 定义一个业务逻辑类,在业务逻辑运行的时候将日志进行打印(方法之前,方法运行结束,方法出现异常等)
    • 前置通知(@Before):logStart:在目标方法(div)运行之前运行 参数列表传入joinPoint可获取到方法的相关属性,且该参数必须放在第一个参数,否则无法识别
    • 后置通知(@After):logEnd:在目标方法(div)运行之后运行,无论方法正常结束还是异常结束
    • 返回通知(@AfterReturning(returning可以指定封装返回值的参数)):logReturn:在目标方法(div)正常返回之后运行
    • 异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行
    • 环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.proceed())
  3. 给切面类的目标方法标注何时何地运行(切点表达式)
  4. 将切面类和目标和业务逻辑类(目标方法所在类)都加入到容器中;
  5. 告诉Spring哪个类是切面类(给切面类上加一个注解@Aspect)
  6. 需要给配置类加一个@EnableAspectJAutoProxy【开启基于注解的aop模式】
@Aspect
public class LogAspects {
    
    

    @Pointcut("execution(public int top.nnzi.aop.AOPTest.*(..))")
    public void pointCut(){
    
    };


    @Before("pointCut()")
    public void logStart(JoinPoint joinPoint) {
    
    
        System.out.println(joinPoint.getSignature().getName()+"运行,参数列表是:"+ Arrays.asList(joinPoint.getArgs()));
    }

    @After("pointCut()")
    public void logEnd (JoinPoint joinPoint) {
    
    
        System.out.println(joinPoint.getSignature().getName()+"结束");
    }

    @AfterReturning(value = "pointCut()",returning = "result")
    public void logReturn (JoinPoint joinPoint,Object result) {
    
    
        System.out.println(joinPoint.getSignature().getName()+"正常返回,结果为:"+ result);
    }

    @AfterThrowing(value = "pointCut()",throwing = "exception")
    public void logException (JoinPoint joinPoint,Exception exception) {
    
    
        System.out.println(joinPoint.getSignature().getName()+"抛出异常:"+exception);
    }


}
@Configuration
@ComponentScan(value = "top.nnzi.bean")
@EnableAspectJAutoProxy
public class MyConfig {
    
    
    @Bean
    public AOPTest aopTest () {
    
    
        return new AOPTest();
    }

    @Bean
    public LogAspects logAspects () {
    
    
        return new LogAspects();
    }
}

4.2 AOP的原理:

【看给容器中注册了什么组件,这个组件什么时候工作,包括这个组件工作时候的功能】

4.2.1 @EnableAspectJAutoProxy是什么?

  1. @Import(AspectJAutoProxyRegistrar.class):给容器导入AspectJAutoProxyRegistrar.class(利用AspectJAutoProxyRegistrar自定义给容器中注册bean)
  2. 执行registerBeanDefinitions方法中的:AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
  3. 给容器中注册"internalAutoProxyCreator"=AnnotationAwareAspectJAutoProxyCreator的bean(BeanDefinition),即bean的定义信息:
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);

4.2.2 AnnotationAwareAspectJAutoProxyCreator

继承关系
继承关系:
AnnotationAwareAspectJAutoProxyCreator extends
AspectJAwareAdvisorAutoProxyCreator extends
AbstractAdvisorAutoProxyCreator extends
AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
关注后置处理器(在bean初始化完成前后做事情)(SmartInstantiationAwareBeanPostProcessor)、自动装配beanFactory(BeanFactoryAware)

bean的生命周期创建过程在下面Spring容器创建过程中讲解

4.2.3 AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor类型的后置处理器】的作用

createBean方法中:

  1. 每一个bean创建之前调用postProcessBeforeInstantiation();
    • 判断当前bean是否在advisedBeans(保存了所有需要增强的bean)中
    • 判断当前bean是否是基础类型的Advice、PointCut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect):isInfrastructureClass(beanClass)
    • 判断是否需要跳过:shouldSkip(beanClass, beanName):
      • 获取候选的增强器(切面里面的通知方法)【List candidateAdvisors】
        每一个封装的通知方法的增强器是InstantiationModelAwarePointcutAdvisor类型
      • 判断每个增强器是否是AspectJPointcutAdvisor类型的,如果是就返回true
      • 否则永远返回false

doCreateBean方法中:

  1. 创建对象调用postProcessAfterInitialization() :return wrapIfNecessary(bean, beanName, cacheKey);
  2. 获取当前bean的所有增强器(通知方法):
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    • 找到候选的所有增强器(找到哪些通知方法是需要切入到当前bean方法的)
    • 获取到能在bean使用的增强器
    • 给增强器排序
  3. 保存当前bean在advisedBeans中
  4. 如果当前bean需要增强,创建当前bean的代理对象:
    Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    • 获取所有增强器(通知方法):
      Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    • 保存到adviseFactory:
      proxyFactory.addAdvisors(advisors);
    • 创建代理对象,Spring自动决定:
      return new JdkDynamicAopProxy(config);jdk动态代理
      return new JdkDynamicAopProxy(config);cglib动态代理
  5. 容器中返回当前组件使用cglib增强了的代理对象
  6. 以后从容器中获取到就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程

4.2.4 目标方法执行流程

容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细的信息(比如增强器,目标对象等等)
在这里插入图片描述

4.2.4.1CglibAopProxy.intercept();拦截目标方法的执行
  1. 根据ProxyFactory对象获取目标方法将要执行的拦截器链:
    List chain =this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    • 保存所有拦截器:
      List interceptorList = new ArrayList<>(config.getAdvisors().length);
      有一个默认的ExposeInvocationInterceptor.ADVISOR和自己配置的四个InstantiationModelAwarePointcutAdvisor
    • 遍历所有增强器,将其转为MethodInterceptor:registry.getInterceptors(advisor):
      • 如果是 MethodInterceptor,直接加入到List中返回
      • 如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor
      • 转换完成,返回MethodInterceptor数组,即拦截器链

拦截器链:每一个通知方法利用MethodInterceptor机制包装成拦截器链

  1. 如果没有拦截器链,直接执行目标方法
  2. 如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链等信息传入创建一个CglibMethodInvocation对象,并调用proceed()方法获取返回值。
    retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
  3. 拦截器链的触发过程(proceed()的方法中),拦截器链的机制保证通知方法与目标方法的执行顺序
    • 如果没有拦截器,或者拦截器的索引和拦截器数组-1大小一样(执行到最后一个拦截器),直接执行目标方法后返回;
      currentInterceptorIndex=this.interceptorsAndDynamicMethodMatchers.size() - 1
    • 获取到当前下标拦截器interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex)(将当前拦截器的索引+1)
    • 调用((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); this为cglib的代理对象,再调用proceed,直到MethodBeforeAdviceInterceptor时会调用前置通知,然后再调用proceed。
    • MethodBeforeAdviceInterceptor方法返回后执行目标方法后到AspectJAfterAdvice的proceed中,执行后置通知
    • AspectJAfterAdvice执行完成后又返回到AfterReturningAdviceInterceptor方法中,执行afterReturning()方法(方法执行过程中间不出任何异常,如果出了异常会被上层AspectJAfterThrowingAdvice捕获)
    • 如果出现异常AspectJAfterThrowingAdvice会捕获到执行invokeAdviceMethod()方法
    • 随后回到最初的proceed方法,返回,过程中一共进行了5次压栈操作
      在这里插入图片描述

4.2.5 总结

  1. @EnableAspectJAutoProxy 开启AOP功能
  2. @EnableAspectJAutoProxy会注册一个AnnotationAwareAspectJAutoProxyCreator组件
  3. AnnotationAwareAspectJAutoProxyCreator是一个后置处理器
  4. 容器创建流程:
    • registerBeanPostProcessor()注册所有后置处理器,会创建AnnotationAwareAspectJAutoProxyCreator对象
    • finishBeanFactoryInitialize()初始化剩下的单实例bean
      • 创建业务逻辑组件和切面组件
      • AnnotationAwareAspectJAutoProxyCreator会拦截组件的创建过程
      • 组件创建完成之后,判断组件是否需要增强:如果是:切面的通知方法包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib代理)
  5. 执行目标方法
    • 代理对象执行目标方法
    • CglibProxy.intercept()拦截器拦截
      • 得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
      • 利用拦截器的链式机制,依次进入每一个拦截器进行执行
      • 效果:
        正常执行:前置通知->目标方法->后置通知->返回通知
        异常执行:前置通知->目标方法->后置通知->异常通知
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    
    
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
    
    
			if (this.advisedBeans.containsKey(cacheKey)) {
    
    
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
    
    
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
    
    
			if (StringUtils.hasLength(beanName)) {
    
    
				this.targetSourcedBeans.add(beanName);
			}
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}
	protected boolean isInfrastructureClass(Class<?> beanClass) {
    
    
		boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
				Pointcut.class.isAssignableFrom(beanClass) ||
				Advisor.class.isAssignableFrom(beanClass) ||
				AopInfrastructureBean.class.isAssignableFrom(beanClass);
		if (retVal && logger.isTraceEnabled()) {
    
    
			logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
		}
		return retVal;
	}
	@Override
	protected boolean shouldSkip(Class<?> beanClass, String beanName) {
    
    
		// TODO: Consider optimization by caching the list of the aspect names
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		for (Advisor advisor : candidateAdvisors) {
    
    
			if (advisor instanceof AspectJPointcutAdvisor &&
					((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
    
    
				return true;
			}
		}
		return super.shouldSkip(beanClass, beanName);
	}
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    
    
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
    
    
			return bean;
		}
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
    
    
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
    
    
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
    
    
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}
	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
    
    

		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
    
    
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}

		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

		if (!proxyFactory.isProxyTargetClass()) {
    
    
			if (shouldProxyTargetClass(beanClass, beanName)) {
    
    
				proxyFactory.setProxyTargetClass(true);
			}
			else {
    
    
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}

		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
    
    
			proxyFactory.setPreFiltered(true);
		}

		return proxyFactory.getProxy(getProxyClassLoader());
	}
	@Override
	@Nullable
	public Object proceed() throws Throwable {
    
    
		//	We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    
    
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
    
    
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
    
    
				return dm.interceptor.invoke(this);
			}
			else {
    
    
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				return proceed();
			}
		}
		else {
    
    
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

五.声明式事务

  • 给方法上面标注@Transactional 标识当前方法是一个事务方法
  • @EnableTransactionManagement开启基于注解的事务管理功能
  • 配置事务管理器来控制事务
    @Bean
    public PlatformTransactionManager platformTransactionManager (DateSource dateSource) {
    
    
        return new DataSourceTransactionManager(dateSource);
    }

六. BeanPostProcessor

BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的

  1. BeanFactoryPostProcessor:beanFactory的后置处理器,在beanFactory标注初始化后调用,所以bean的定义已经保存加载到beanFactory,但是bean的实例还未创建
    流程
    • ioc容器创建对象
    • invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessors
      • String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);找到所有postProcessor的名字执行方法
      • 在初始化创建其它组件前面执行

BeanDefinitionRegistryPostProcessor
是BeanFactoryPostProcessor的子接口,BeanDefinitionRegistry是Bean定义信息的保存中心,BeanFactory就是按照其中保存的bean的定义信息创建bean实例的。
postProcessBeanDefinitionRegistry()方法,在所有bean定义信息将要被加载到,但是bean实例还未创建,优先于BeanFactoryPostProcess执行,可以利用其给容器中再来添加一些组件

七. ApplicationListener

ApplicationListener:监听容器中发布的事件,事件驱动模型的开发
实现ApplicationListener< E extends ApplicationEvent >接口:监听ApplicationEvent及其子类的相关事件,只要容器中有相关事件发布,我们就能监听到这个事件,如

  • ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件
  • ContextClosedEvent:关闭容器发布这个事件

或者自己发布事件:自定义发布一个事件 ioc容器.publishEvent(ApplicationEvent);

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
    
    

	/**
	 * Handle an application event.
	 * @param event the event to respond to
	 */
	void onApplicationEvent(E event);

}

注解形式:
@EventListener(class={}):可以在普通业务逻辑组件的方法上标注该注解来监听事件。

八. Spring容器创建过程

Spring容器的refresh()【创建刷新】

@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.
				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();
			}

1. BeanFactory的创建及预准备工作

  1. prepareRefresh()刷新前的预处理
    • initPropertySources();初始化一些属性设置;子类自定义个性化属性设置方法;
    • getEnvironment().validateRequiredProperties();检验属性的合法等;
    • this.earlyApplicationEvents = new LinkedHashSet<>();保存容器中的一些早期事件
  2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory() 获取BeanFactory
    • refreshBeanFactory();刷新【创建】beanFactory: 在GenericApplicationContext对象构造时this.beanFactory=new DefaultListableBeanFactory();并设置标识ID
    • 通过getBeanFactory();​ 返回刚才GenericApplicationContext创建的BeanFactory【DefaultListableBeanFactory】对象
    • prepareBeanFactory(beanFactory);BeanFactory的预准备工作(BeanFactory进行一些设置):
      • 设置BeanFactory的类加载器、支持表达式解析器
      • 添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
      • 设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware…
      • 注册可以解析的自动装配;我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
      • 添加BeanPostProcessor【ApplicationListenerDetector】
      • 给BeanFactory中注册一些能用的组件: environment【ConfigurableEnvironment】、 systemPropertie【Map<String,Object>】、​ systemEnvironment【Map<String,Object>】
  3. postProcessBeanFactory(beanFactory);BeanFactory准备工作完成后进行的后置处理工作
    • 本身是一个空方法,子类通过重写这方法在BeanFactory创建并预准备完成以后做进一步的设置。

2.invokeBeanFactoryPostProcessors(beanFactory): 执行BeanFactoryPostProcessor的方法

BeanFactoryPostProcessor:BeanFactory的后置处理器,在BeanFactory标注初始化之后执行​ 有两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

  1. 执行invokeBeanFactoryPostProcessors方法
  2. 获取所有BeanDefinitionRegistryPostProcessor
    • 先执行实现了PriorityOrdered优先级接口的、再执行实现了Ordered的接口的、最后执行其它的
  3. 获取所有BeanFactoryPostProcessor
    • 先执行实现了PriorityOrdered优先级接口的、再执行实现了Ordered的接口的、最后执行其它的

3.registerBeanPostProcessors(beanFactory); 注册BeanPostProcessor

  1. BeanPostProcessor(Bean的后置处理器)【拦截Bean的创建过程】
  2. 不同类型的BeanPostProcessor,在Bean创建前后的执行时机是不一样的
    ​ 有如下几类:
    • BeanPostProcessor
    • DestructionAwareBeanPostProcessor
    • InstantiationAwareBeanPostProcessor
    • SmartInstantiationAwareBeanPostProcessor
    • MergedBeanDefinitionPostProcessor【internalPostProcessors】
  3. 执行流程:
    • 获取所有的BeanPostProcessor;
      ​ 后置处理器都默认可以通过PriorityOrdered、Ordered来指定优先级
    • 先注册PriorityOrdered优先级接口的BeanPostProcessor
      ​ 把每一个BeanPostProcessor添加到BeanFactory中,
      ​ beanFactory.addBeanPostProcessor(postProcessor)
    • 再注册了实现Ordered接口的
    • 最后注册其它没有实现任何优先级接口的
    • 最终注册MergedBeanDefinitionPostProcessor类型的
    • 注册一个ApplicationListenerDetector;来在Bean创建完成后检查是否ApplicationListeneraddApplicationListener((ApplicationListener<?>) bean);

4. initMessageSource();初始化MessageSource组件(做国际化功能;消息绑定;消息解析等功能):

  1. 获取BeanFactory
  2. 看容器中是否有id为messageSource,类型是MessageSource的组件如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource,​ MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取
  3. 把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource;调用其方法可以获得相关配置属性
    beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);

5. initApplicationEventMulticaster();初始化事件派发器【多播器】

  1. 获取BeanFactory
  2. 从BeanFactory获取applicationEventMulticaster的组件
  3. 如果上一步没有配置;创建一个SimpleApplicationEventMulticaster
  4. 将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入
    beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);

6. onRefresh();留给子容器(子类)

  1. 空方法,子类重写这个方法,在容器刷新的时候可以自定义逻辑

7. registerListeners();给容器中将所有项目里面的ApplicationListener注册进来

  1. 从容器中拿到所有ApplicationListener组件
  2. 将每个监听器添加到事件派发器中
    ​getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
  3. 派发之前步骤产生的事件

8. finishBeanFactoryInitialization(beanFactory);初始化所有剩下的单实例bean

beanFactory.preInstantiateSingletons();初始化剩下的单实例bean

  1. 获取容器中的所有Bean,依次进行初始化和创建对象
    ​ List beanNames = new ArrayList<>(this.beanDefinitionNames);
  2. 遍历beanNames获取bean 的定义信息;
    ​ RootBanDefinition bd = getMergedLocalBeanDefinition(beanName);
  3. 判断Bean不是抽象的,是单实例的,不是懒加载得
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit())
    • 判断是否是FactoryBean;是否是实现FactoryBean接口的Bean
      if (isFactoryBean(beanName))
    • 如果是,利用工厂方法创建对象getObject();
    • 不是工厂Bean,利用getBean(过程如下)(beanName);创建对象
    • 所有Bean都利用getBean创建完成以后;​ 检查所有的Bean是否是SmartInitializingSingleton接口类型的,如果是就执行 afterSingletonsInstantiated()方法;

getBean过程:
getBean(beanName);ioc.getBean;

  1. AbstractBeanFactory.doGetBean();
  2. 先获取缓存中保存的单实例bean,如果能获取到,说明这Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)从getSingleton方法中singletonObjects=new ConcurrentHashMap<String,Object>属性中获取到
  3. 缓存中获取不到,开始Bean的创建对象流程:
    • 标记当前Bean已经被创建,markBeanAsCreated(beanName);防止多线程bean重复创建
    • 获取Bean的定义信息:final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    • 获取当前Bean依赖的其它Bean;如果有,按照getBean()把依赖的Bean先创建出来
    • 启动单实例Bean的创建流程:

单实例Bean的创建流程:

  1. createBean(beanName,mbd,args);
    • Object bean = resolveBeforeInstantiation(beanName, mbdToUse);先让BeanPostProcessor【InstantiationAwareBeanPostProcessor】先拦截返回代理对象。先触发所有InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation()方法,如果有返回值调用postProcessAfterInstantiation()方法
    • 如果没有返回bean,调用doCreateBean();Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      • 利用工厂方法或者对象的构造器等创建bean实例:createBeanInstance(beanName, mbd, args);

      • applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

      • 为bean的属性赋值:populateBean(beanName, mbd, instanceWrapper);
        赋值之前:

        • 拿到InstantiationAwareBeanPostProcessor类型的后置处理器,执行postProcessAfterInstantiation();
        • 拿到InstantiationAwareBeanPostProcessor类型的后置处理器,执行postProcessProperties();

        赋值:

        • 应用Bean属性的值:为属性利用setter方法等进行赋值applyPropertyValues(beanName, mbd, bw, pvs);
      • bean初始化:initializeBean(beanName, exposedObject, mbd);(生命周期中介绍)

      • 注册bean的销毁方法:registerDisposableBeanIfNecessary(beanName, bean, mbd);

    • Bean的实例创建完成,将bean添加到缓存中:addSingleton(beanName, singletonObject);

ioc容器就是这些Map;很多Map里面保存了单实例bean,环境信息等…

9. finishRefresh();完成BeanFactory初始化创建工作;IOC容器就创建完成

  1. clearResourceCaches();清理一些资源缓存
  2. initLifecycleProcessor();初始化声明周期有关的后置处理器,允许我们写一个LifecycleProcessor的实现类,可以在BeanFactory进行到特定生命周期时进行调用
    ​ 默认从容器中找是否有LifeCycleProcessor的组件,如果没有,默认会创建一个 new DefaultLifecycleProcessor();然后加入到容器中
  3. getLifecycleProcessor().onRefresh();拿到所有前面定义的生命周期处理器回调onRefresh()方法
  4. publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件
  5. LiveBeansView.registerApplicationContext(this);

九. Spring容器创建总结

  1. Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息
    • xml注册bean < bean id="" class = “”>
    • 使用注解;@Service、@Bean、@Component、…
  2. Spring容器会在合适的时机创建这些Bean
    • 用到这个bean的时候,利用getBean方法创建bean,创建好以后保存在容器中
    • 统一创建剩下所有bean的时候,即finishBeanFactoryInitialize();
  3. 后置处理器
    每一个bean创建完成,都会使用各种后置处理器进行处理,来增强bean 的功能,如:
    + AutowiredAnnotationBeanPostProcessor会处理自动注入功能
    + AnnotationAwareAspectJAutoProxyCreator来做AOP功能
  4. 事件驱动模型:
    • ApplicationListener:事件监听
    • ApplicationEventMulticaster:事件派发

猜你喜欢

转载自blog.csdn.net/weixin_48922154/article/details/113783458
今日推荐