`

spring之ApplicationContextAware接口

阅读更多
//该接口会帮你注入ApplicationContext

public interface ApplicationContextAware extends Aware {
	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

//其实现原理为在创建bean的时候由spring框架来注入:
//该类位于AbstractAutowireCapableBeanFactory下
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, new ObjectFactory<Object>() {
				@Override
				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
			        //初始化bean
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}


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 {
			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;
	}

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			result = beanProcessor.postProcessBeforeInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}


//该类位于ApplicationContextAwareProcessor下
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(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					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(
						new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
			}
			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);
			}
		}
	}

分享到:
评论

相关推荐

    spring入门 aware接口实现

    通过aware接口,可以对spring相应...首先创建一个类,实现ApplicationContextAware接口 , 该借口需要实现 setApplicationContext方法,该方法的参数由容器传递进来。 这样,bean 就获得了ApplicationContext这个资源

    spring-aware接口实现与bean作用域(spring多容器层面)

    `ApplicationContextAware`是其中的一个典型接口,当我们想要在非托管类(即非Spring Bean)中获取Spring容器中的其他Bean时,可以使用这个接口。 `ApplicationContextAware`接口提供了`setApplicationContext`方法...

    Spring Aware标记接口使用案例解析

    ApplicationContextAware 是 Spring 中最常用的 Aware 接口之一,它提供了对ApplicationContext对象的访问能力。通过实现 ApplicationContextAware 接口,Bean 对象可以获取到ApplicationContext 对象,从而访问 ...

    Spring各种回调接口[定义].pdf

    2. **ApplicationContextAware**:此接口允许Bean直接访问ApplicationContext容器。通过实现`setApplicationContext(ApplicationContext applicationContext)`方法,Bean可以获取到容器对象,从而可以访问其他Bean、...

    Spring实现Aware接口自定义获取bean的两种方式

    在Spring编程中,经常需要根据bean的名称来获取相应的bean对象,这时候,可以通过实现BeanFactoryAware和ApplicationContextAware接口来满足需求。 一、实现BeanFactoryAware接口 BeanFactoryAware接口是Spring...

    17. Spring Boot普通类调用bean【从零开始学Spring Boot】

    - 实现ApplicationContextAware接口,Spring会在初始化时自动注入ApplicationContext。 - 使用`@Resource`注解,与`@Autowired`类似,但更适用于字段注入,并且支持JSR 250规范。 - 静态ApplicationContext的...

    netty-spring-mvc-master.rar_netty_netty spring_netty4 spring_s

    这通常可以通过实现Spring的ApplicationContextAware接口来实现,这样可以在Netty的启动过程中获取到Spring的ApplicationContext,从而获取到需要的服务实例,例如MySQL的连接池。 在具体实现中,可以创建一个...

    Spring特性——Aware感知特性

    ApplicationContextAware接口扩展了BeanFactoryAware,提供了`setApplicationContext(ApplicationContext applicationContext)`方法。ApplicationContext比BeanFactory更加强大,提供了更多功能,如消息资源处理、...

    spring监听器共20页.pdf.zip

    1. **理解ApplicationContextAware接口**:当一个Bean实现了ApplicationContextAware接口,Spring容器会在Bean初始化后,自动将ApplicationContext对象注入到Bean中,使得Bean可以获取到上下文中的其他Bean。...

    Struts2和Spring整合

    - 创建Action类:Action类需要实现Spring的ApplicationContextAware接口,以便获取Spring的ApplicationContext,并通过它来获取依赖的服务。 - 结合使用:在Action中通过@Autowired注解或者ApplicationContext获取...

    Spring源码学习八:常用的扩展接口详解1

    3. **ApplicationContextAware接口**: 这个接口有一个`setApplicationContext(ApplicationContext)`方法。实现这个接口的类能够在Bean加载过程中获取到Spring应用上下文`ApplicationContext`,从而可以访问容器中...

    用maven整合struts+spring+hibernate

    - 将Struts 2的Action与Spring的Bean关联,通常通过实现Spring的ApplicationContextAware接口。 - 使用Spring的JdbcTemplate或Hibernate的Session进行数据库操作。 6. 测试与调试: 在整合完成后,可以通过单元...

    com-spring-ioc-demo:源码主要是学习Spring IOC的原理,以及对Bean的注册及控制,主要运用以下类对Spring进行扩展学习:BeanPostProcessor,BeanFactoryAware,BeanNameAware,ApplicationContextAware,FactoryBean,BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor,BeanPostProcessor,ResourceLoaderA

    com-spring-ioc-demo:源码主要是学习Spring IOC的原理,以及对Bean的注册及控制,主要运用以下类对Spring进行扩展学习:BeanPostProcessor,BeanFactoryAware,BeanNameAware,ApplicationContextAware,FactoryBean...

    获取spring容器的方法

    本文将深入探讨几种常见的获取Spring容器的方法,包括使用`ApplicationContext`、通过`ServletContext`、利用`ApplicationObjectSupport`、`WebApplicationObjectSupport`以及实现`ApplicationContextAware`接口等。...

    Spring中关于Bean的管理的课件

    4. **Spring的应用上下文(ApplicationContext)**:ApplicationContext是Spring的主要接口之一,它提供了获取Bean、处理消息和事件等功能,是Spring应用中的主要入口点。 5. **构造注入(constructor injection)*...

    Spring官方文档之核心篇

    Spring还支持自定义Bean的属性,包括Aware接口的使用,例如ApplicationContextAware或BeanNameAware。 - **Aware接口**:通过实现特定的Aware接口,Bean可以获得Spring容器中的资源和信息。 - **自定义属性**:...

    详细的Spring配置和Spring Boot-外文翻译

    为此,Spring提供了两个接口:BeanNameAware和ApplicationContextAware(在第3章末尾介绍)。这两个接口分别允许你的bean获取其分配的名字并引用它的ApplicationContext。本章将涵盖实现这些接口以及在应用程序中...

    Spring Bean生命周期.pdf

    其中,Spring Bean生命周期的管理是Spring框架的核心功能之一,它涉及Spring容器如何创建、配置以及销毁Bean的整个过程。理解Spring Bean的生命周期对于开发高效和可维护的Java应用至关重要。 Spring Bean生命周期...

    struts2 spring3 mybatis3整合简单例子

    接下来,定义Action类,通常这个类会实现Spring的ApplicationContextAware接口,以便于在Action中注入需要的服务。Action类会通过注解或者XML配置与Struts2的动作映射关联起来。 然后,创建Service层,这部分通常由...

    springmvc spring 两套上下文问题

    两套上下文之间的通信是通过ApplicationContextAware接口来实现的。如果某个Bean需要访问到Spring的全局ApplicationContext,它可以实现这个接口,Spring会在初始化时自动注入ApplicationContext实例。这样,...

Global site tag (gtag.js) - Google Analytics