SpringMVC最核心的IOC的控制反转,动态的向某个对象提供它所需要的其他对象,例如:对象A时,需要对象B时,这时不像以前我们之前要在A对象里实例化B对象,这时B对象的实例化由IOC容器会主动创建一个对象B然后注入到对象A里,提供使用。我们项目开发中,最经常用到,那怎么实现实例Bean并依赖注入呢?我们今天带着这些问题来通过SpringMVC源代码进行深入的解析。这篇介绍不对注解实例化和注入进行讲解,这个放在后面在介绍。
我们平常写的一个类,并依赖调用了类的某个方法,这时需要依赖那个类已经实例化,这样才能调用,这些都是交给IOC控制反转,这是我们写的一个类,代码如下
- package cn.test.service.impl;
- import cn.test.service.TestService2;
- public class TestServiceImpl2 implements TestService2{
- }
package cn.test.service.impl;
import cn.test.service.TestService2;
public class TestServiceImpl2 implements TestService2{
}
- package cn.test.service.impl;
- import cn.test.service.TestService;
- import cn.test.service.TestService2;
- public class TestServiceImpl implements TestService{
- private TestServiceImpl(){
- System.out.println("xx");
- }
- private TestService2 testService2;
- public TestService2 getTestService2() {
- return testService2;
- }
- public void setTestService2(TestService2 testService2) {
- this.testService2 = testService2;
- }
- }
package cn.test.service.impl;
import cn.test.service.TestService;
import cn.test.service.TestService2;
public class TestServiceImpl implements TestService{
private TestServiceImpl(){
System.out.println("xx");
}
private TestService2 testService2;
public TestService2 getTestService2() {
return testService2;
}
public void setTestService2(TestService2 testService2) {
this.testService2 = testService2;
}
}
在配置文件配置了对应的Bean
- <span style="font-size:18px;"> <bean id="testService" class="cn.test.service.impl.TestServiceImpl" >
- <property name="testService2" ref="testService2"></property>
- </bean>
- <bean id="testService2" class="cn.test.service.impl.TestServiceImpl2" ></bean></span>
<span style="font-size:18px;"> <bean id="testService" class="cn.test.service.impl.TestServiceImpl" >
<property name="testService2" ref="testService2"></property>
</bean>
<bean id="testService2" class="cn.test.service.impl.TestServiceImpl2" ></bean></span>
那SpringMVC
怎么实现实例
B
ean并依赖注入?我们带着上面实现的代码来解析。
首先我们先回到refresh这个方法,在上一篇Bean解析和注册,大家应该还记得吧,里面有postProcessBeanFactory这个方法,就是实例化bean的,我们带着好奇心来分析了解。当Bean定义资源被载入IoC容器之后,容器将Bean定义资源解析为容器内部的数据结构,然后BeanDefinition注册到容器中,AbstractApplicationContext类中的finishBeanFactoryInitialization方法对配置了属性的Bean进行初始化过程,源码如下:
- protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
- // CONVERSION_SERVICE_BEAN_NAME为转换服务(ConversionService)
- if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
- beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
- beanFactory.setConversionService(
- beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
- }
- // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
- String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
- for (String weaverAwareName : weaverAwareNames) {
- getBean(weaverAwareName);
- }
- // Stop using the temporary ClassLoader for type matching.
- beanFactory.setTempClassLoader(null);
- // Allow for caching all bean definition metadata, not expecting further changes.
- beanFactory.freezeConfiguration();
- // 对bean进行实例化
- <span style="color:#ff0000;">beanFactory.preInstantiateSingletons();</span>
- }
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// CONVERSION_SERVICE_BEAN_NAME为转换服务(ConversionService)
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// 对bean进行实例化
<span style="color:#ff0000;">beanFactory.preInstantiateSingletons();</span>
}
preInstantiateSingletons由对bean进行实例化由子类DefaultListableBeanFactory来实现的。源代码:
- public void preInstantiateSingletons() throws BeansException {
- if (this.logger.isInfoEnabled()) {
- this.logger.info("Pre-instantiating singletons in " + this);
- }
- List<String> beanNames;
- synchronized (this.beanDefinitionMap) {
- // Iterate over a copy to allow for init methods which in turn register new bean definitions.
- // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
- beanNames = new ArrayList<String>(this.beanDefinitionNames);
- }
- for (String beanName : beanNames) {
- RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
- if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
- 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>() {
- public Boolean run() {
- return ((SmartFactoryBean<?>) factory).isEagerInit();
- }
- }, getAccessControlContext());
- }
- else {
- isEagerInit = (factory instanceof SmartFactoryBean &&
- ((SmartFactoryBean<?>) factory).isEagerInit());
- }
- if (isEagerInit) {
- getBean(beanName);
- }
- }
- else {
- <span style="color:#cc0000;">getBean(beanName);</span>
- }
- }
- }
- }
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isInfoEnabled()) {
this.logger.info("Pre-instantiating singletons in " + this);
}
List<String> beanNames;
synchronized (this.beanDefinitionMap) {
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
beanNames = new ArrayList<String>(this.beanDefinitionNames);
}
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
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>() {
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
<span style="color:#cc0000;">getBean(beanName);</span>
}
}
}
}
getBean(beanName);对bean进行实例化并对属性依赖进行注入过程。前面解析的代码不重要,主要是入口点,接下来才是重点, 创建bean时,如果缓存中有单例Bean时,就从缓存获取,如果没有就新建,通过匿名的内部类来创建Bean时根据Bean的作用域来创建的,有单实例作用域、原型作用域、Request等。源代码如下:
- public Object getBean(String name) throws BeansException {
- return doGetBean(name, null, null, false);
- }
- @SuppressWarnings("unchecked")
- protected <T> T doGetBean(
- final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
- throws BeansException {
- //如果指定的是别名,将别名转换为规范的Bean名称
- final String beanName = transformedBeanName(name);
- Object bean;
- // 如果缓存中有单例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);
- }
- else {
- // Fail if we're already creating this bean instance:
- // We're assumably within a circular reference.
- if (isPrototypeCurrentlyInCreation(beanName)) {
- throw new BeanCurrentlyInCreationException(beanName);
- }
- // 获取父工厂
- BeanFactory parentBeanFactory = getParentBeanFactory();
- //检查BeanDefinition是否有当前的BeanFactory,如果没有,就到父工厂去查找
- if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
- // Not found -> check parent.
- String nameToLookup = originalBeanName(name);
- if (args != null) {
- // Delegation to parent with explicit args.
- return (T) parentBeanFactory.getBean(nameToLookup, args);
- }
- else {
- // No args -> delegate to standard getBean method.
- return parentBeanFactory.getBean(nameToLookup, requiredType);
- }
- }
- if (!typeCheckOnly) {
- markBeanAsCreated(beanName);
- }
- try {
- //看说明(2)
- final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
- //是否为抽象的、是否Prototype
- checkMergedBeanDefinition(mbd, beanName, args);
- // 获取当前Bean所有依赖Bean的名称
- String[] dependsOn = mbd.getDependsOn();
- if (dependsOn != null) {
- for (String dependsOnBean : dependsOn) {
- //递归调用getBean方法
- getBean(dependsOnBean);
- //注册依赖的bean
- registerDependentBean(dependsOnBean, beanName);
- }
- }
- // 创建单例bean实例
- if (mbd.isSingleton()) {
- //内部类,实现创建bean
- sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
- public Object getObject() throws BeansException {
- try {
- //创建bean
- return createBean(beanName, mbd, args);