Spring源碼分析-IOC之Aware

Aware:已感知的,意識到的,所以這些接口從字面意思應該是能感知到所有Aware前面的含義,Spring中提供了一些Aware相關接口,比如BeanNameAware,BeanFactoryAware,ApplicationContextAware等,下面我們來看下BeanNameAware,BeanNameAware就是將name注入實例,我們來看下具體的應用:

package com.ck.bean;


import java.io.Serializable;

import org.springframework.beans.factory.BeanNameAware;

public class Person implements BeanNameAware, Serializable{
	
	private static final long serialVersionUID = 1L;

	
	private String name;
	

	@Override
	public void setBeanName(String name) {
		this.name = name;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}
	
}

看下配置文件:

<?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"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">

	<bean id="person" class="com.ck.bean.Person"/>
</beans>

看下測試代碼:

package com.ck.ioc;


import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.ck.bean.Person;


public class IocTest {
	@Test
	public void test() {
		ConfigurableApplicationContext ctx = new FileSystemXmlApplicationContext( "src/main/resources/applicationContext.xml");
		Person person = ctx.getBean(Person.class);
		System.out.println(person.getName());
	}

}

我們看下測試結果:

四月 04, 2019 8:31:16 下午 org.springframework.context.support.FileSystemXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@3c679bde: startup date [Thu Apr 04 20:31:16 CST 2019]; root of context hierarchy
四月 04, 2019 8:31:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from file [X:\CK\stsws\springWeb\src\main\resources\applicationContext.xml]
person

我們看到實現了BeanNameAware的接口,最終在實例中獲得了在Spring容器中name,spring中的其他aware與BeanNameAware打通小異,各位可以嘗試下,我們來看下aware在Spring中的實現原理,我們根據前面介紹的 Spring源碼分析-IOC之InitializingBean代碼繼續往下走:

AbstractAutowireCapableBeanFactory中的initializaBean:

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

    //此處我們可以看到Aware實現的地方
	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);
			}
		}
	}

通過代碼我們可以一目瞭然的看到Aware的應用以及在Spring中的應用,這些過程都是在Spring容器實例化bean的地方實現的.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章