IOC原理——初始化bean

各种初始化方法及执行顺序见《Bean 生命周期 钩子》。初始化bean在IOC初始化时的执行时机见《IOC原理——创建非懒加载的单实例bean》,直接在文章中搜索initializeBean,锁定位置。
AbstractAutowireCapableBeanFactory#initializeBean

	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			// 执行 aware,传入所需对象。
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// 1. BeanPostProcessor 前置处理,见《BeanPostProcessor——执行时机》,文末有链接
			// 2. 执行 @PostConstruct 注解标注的方法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 执行初始化方法,InitializingBean 接口的 afterPropertiesSet 方法和 @Bean 的 initMethod
			invokeInitMethods(beanName, wrappedBean, mbd);
		} // catch ...
		if (mbd == null || !mbd.isSynthetic()) {
			// BeanPostProcessor 后置处理,见《BeanPostProcessor——执行时机》,文末有链接
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

invokeAwareMethods

	private void invokeAwareMethods(String beanName, Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

1. 利用BeanPostProcessor实现初始化

就是在bean执行初始化方法前后进行拦截,执行时机详见《BeanPostProcessor——执行时机


2. 执行 @PostConstruct注解

本质也是利用的BeanPostProcessor。具体是利用的CommonAnnotationBeanPostProcessor,该类继承自InitDestroyAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
在构造方法中就默认加入了@PostConstruct注解:

	public CommonAnnotationBeanPostProcessor() {
		setOrder(Ordered.LOWEST_PRECEDENCE - 3);
		setInitAnnotationType(PostConstruct.class);
		setDestroyAnnotationType(PreDestroy.class);
		ignoreResourceType("javax.xml.ws.WebServiceContext");
	}

InitDestroyAnnotationBeanPostProcessor#setInitAnnotationType

	private Class<? extends Annotation> initAnnotationType;
	public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
		this.initAnnotationType = initAnnotationType;
	}

其实是在InitDestroyAnnotationBeanPostProcessor类中通过实现了BeanPostProcessor调用的,本质上仍然是通过BeanPostProcessor实现的:
InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization

	// BeanPostProcessor
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// 在 findLifecycleMetadata 中找到实现了 @PostConstruct 注解的方法
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			// 调用找到的初始化方法
			metadata.invokeInitMethods(bean, beanName);
		} // catch ...
		return bean;
	}

findLifecycleMetadata

	private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
		if (this.lifecycleMetadataCache == null) {
			// Happens after deserialization, during destruction...
			// 具体是在这个方法里实现的
			return buildLifecycleMetadata(clazz);
		}
		// Quick check on the concurrent map first, with minimal locking.
		LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
		if (metadata == null) {
			synchronized (this.lifecycleMetadataCache) {
				metadata = this.lifecycleMetadataCache.get(clazz);
				if (metadata == null) {
					metadata = buildLifecycleMetadata(clazz);
					this.lifecycleMetadataCache.put(clazz, metadata);
				}
				return metadata;
			}
		}
		return metadata;
	}

buildLifecycleMetadata

	private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
		if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
			return this.emptyLifecycleMetadata;
		}

		List<LifecycleElement> initMethods = new ArrayList<>();
		List<LifecycleElement> destroyMethods = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<LifecycleElement> currInitMethods = new ArrayList<>();
			final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				// 如果该方法含有 @PostConstruct 注解,则加入 currInitMethods list
				if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
					LifecycleElement element = new LifecycleElement(method);
					currInitMethods.add(element);
					// log ...
				}
				if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
					currDestroyMethods.add(new LifecycleElement(method));
					// log ...
				}
			});
			
			// 将 currInitMethods list 全部加入 initMethods list
			initMethods.addAll(0, currInitMethods);
			destroyMethods.addAll(currDestroyMethods);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

		// 将 initMethods list 加入 LifecycleMetadata 对象中返回。
		return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
				new LifecycleMetadata(clazz, initMethods, destroyMethods));
	}

LifecycleMetadata类:

		private final Collection<LifecycleElement> initMethods;
		public LifecycleMetadata(Class<?> targetClass, Collection<LifecycleElement> initMethods, Collection<LifecycleElement> destroyMethods) {
			this.targetClass = targetClass;
			this.initMethods = initMethods;
			this.destroyMethods = destroyMethods;
		}
		
		// 该方法就是挨个调用 initMethods 集合里的方法。
		public void invokeInitMethods(Object target, String beanName) throws Throwable {
			Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
			Collection<LifecycleElement> initMethodsToIterate = (checkedInitMethods != null ? checkedInitMethods : this.initMethods);
			if (!initMethodsToIterate.isEmpty()) {
				for (LifecycleElement element : initMethodsToIterate) {
					// log ...
					element.invoke(target);
				}
			}
		}

3. 在invokeInitMethods方法中执行

  1. 执行 InitializingBean接口的 afterPropertiesSet方法
  2. 执行 @BeaninitMethod
	protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			// log ...
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}, getAccessControlContext());
				} // catch ...
			}
			else {
				// 执行 InitializingBean 接口的 afterPropertiesSet 方法
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		if (mbd != null && bean.getClass() != NullBean.class) {
			// 执行 @Bean 的 initMethod
			String initMethodName = mbd.getInitMethodName();
			if (StringUtils.hasLength(initMethodName) &&
					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}

invokeCustomInitMethod

	protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd) throws Throwable {
		// 获得方法名
		String initMethodName = mbd.getInitMethodName();
		Assert.state(initMethodName != null, "No init method set");
		Method initMethod = (mbd.isNonPublicAccessAllowed() ? BeanUtils.findMethod(bean.getClass(), initMethodName) : ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

		if (initMethod == null) {
			if (mbd.isEnforceInitMethod()) {
				throw new BeanDefinitionValidationException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'");
			} else {
				// log ...
				// Ignore non-existent default lifecycle methods.
				return;
			}
		}

		// log ...
		// 根据方法名获得方法
		Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);

		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				ReflectionUtils.makeAccessible(methodToInvoke);
				return null;
			});
			try {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
						() -> methodToInvoke.invoke(bean), getAccessControlContext());
			} // catch ...
		}
		else {
			try {
				ReflectionUtils.makeAccessible(methodToInvoke);
				// invoke,执行方法
				methodToInvoke.invoke(bean);
			} // catch ...
		}
	}

Bean 生命周期 钩子
IOC原理——创建非懒加载的单实例bean
BeanPostProcessor——执行时机

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值