spring源码深度解析(笔记四)--bean的加载
2016-12-19 21:12
555 查看
分析:
1)转换beanName,传入的参数可能是别名、FactoryBean,转换成相应的beanName
2)尝试从缓存加载单例;单例在spring中只会被创建一次,后续获取,就直接从单例缓存中获取。
首先从缓存中加载,若不成功则尝试从singletonFactories中加载;为了避免循环依赖注入,不等bean创建完成就将创建bean的ObjectFactory提早曝光加入到缓存.
3)缓冲中得到的只是bean的原始状态,还需要对bean进行实例化.
4)由于前面的xml解析得到的是GenericBeanDefinition,而后续要用到RootBeanDefinition,所以这里需要一个转换.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
FactoryBean接口,让用户通过实现该接口定制实例化bean的逻辑.
Spring自身就提供了70多个FactoryBean的实现,它们隐藏了实例化一些复杂bean的细节,给上层应用带来了便利.
getObject()返回由FactoryBean创建的bean实例,如果isSingleton()返回true,则该实例会放到spring容器中单实例缓存池中.
当配置文件中<bean>的class属性配置的实现类是FactoryBean时,通过getBean()返回的不是FactoryBean本身,而是FactoryBean中getObject()方法返回的对象。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
先尝试从缓存中获取单例bean:
以上大部分操作是为了循环依赖做的.
无论是从缓存中获取的bean,还是通过不同的scope策略加载的bean都只是最原始的bean状态,并不一定是我们最终要的bean;比如,我们需要对工厂bean进行处理,那么得到的其实是工厂bean初始状态,但是我们真正需要的是工厂bean中定义的factory-method方法中返回的bean,而getObjectForBeanInstance方法就是完成这个工作的.
跟踪此方法,最终在:
以上方法为调用后处理器进行处理.
在spring中有这样一条规则,尽可能保证所有的bean初始化后都会调用注册的BeanPostProcessor的postProcessAfterInitialization方法进行处理;在实际开发过程中可以设计自己的业务逻辑.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
当缓存中不存在已经加载的单例时,要从头开始加载bean:
通过调用参数的getObject()实例化bean.
singletonObjects:用于保存BeanName和创建bean实例之间的关系,bean name --> bean instance
singletonFactories:用于保存BeanName和创建bean的工厂之间的关系,bean name --> ObjectFactory
earlySingletonObjects:也是保存BeanName和创建bean实例之间的关系,与singletonObjects的不同之处在于,当一个单例bean被放到这里面后,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用。
registeredSingletons:用来保存当前所有已注册的bean.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
详细分析上一步中 singletonObject = singletonFactory.getObject() 从参数中获取的过程:
当经过前置处理之后,返回的结果若不为空,那么会直接略过后续的Bean的创建而直接返回结果。AOP功能就是基于这里判断的.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
若不走上面的代理创建实例,则走以下的代码创建bean实例:
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
先来看下spring对循环依赖的处理:
spring容器将每一个正在创建的bean标识符放在一个当前创建bean池中,bean标识符在创建过程中将一直保持在这个池中,因此如果在创建bean过程中发现自己已经在当前创建bean池,将抛出异常;而对于创建完的bean,将从当前创建bean池中清除掉.
1,构造器循环依赖,无法解决,抛出BeanCurrentlyInCreationException异常.
2,单例下的setter循环依赖。
通过spring容器提前暴露刚完成构造器注入但未完成其他步骤(如setter注入)的bean来完成的,通过提前暴露一个单例工厂方法ObjectFactory,从而使其他bean能引用到该bean.
3,prototype不支持循环依赖.
spring在实例化的时候会判断,如果有需要覆盖或者动态替换的方法则使用cglib进行动态代理,若没有则直接使用反射.
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
MyTestBean bean = (MyTestBean) bf.getBean("myTestBean");
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport{ public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly){ //提取对应的beanName final String beanName = transformedBeanName(name); Object bean; //直接尝试从缓存获取或者singletonFactories中的ObjectFactory中获取 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { //缓存中记录的只是原始的bean状态,还需要实例化 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }else { //单例情况下可以解决属性循环依赖,而在原型模式情况下,直接报异常. if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } BeanFactory parentBeanFactory = getParentBeanFactory(); //如果beanDefinitionMap中不包括beanName,这尝试从parentBeanFactory中取 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if (args != null) { return (T) parentBeanFactory.getBean(nameToLookup, args); } else { return parentBeanFactory.getBean(nameToLookup, requiredType); } } //如果不是仅仅做类型检查则是创建bean,这里要进行记录 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { //将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); String[] dependsOn = mbd.getDependsOn(); //若存在依赖则需要递归实例化依赖的bean if (dependsOn != null) { for (String dependsOnBean : dependsOn) { if (isDependent(beanName, dependsOnBean)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); } //缓存依赖调用 registerDependentBean(dependsOnBean, beanName); getBean(dependsOnBean); } } //单例模式的创建 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //原型模式 else if (mbd.isPrototype()) { Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { //指定的Scope上实例化bean String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } //检查需要的类型是否符合bean的实际类型 if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return getTypeConverter().convertIfNecessary(bean, requiredType); } catch (TypeMismatchException ex) { } } return (T) bean; } }
1)转换beanName,传入的参数可能是别名、FactoryBean,转换成相应的beanName
2)尝试从缓存加载单例;单例在spring中只会被创建一次,后续获取,就直接从单例缓存中获取。
首先从缓存中加载,若不成功则尝试从singletonFactories中加载;为了避免循环依赖注入,不等bean创建完成就将创建bean的ObjectFactory提早曝光加入到缓存.
3)缓冲中得到的只是bean的原始状态,还需要对bean进行实例化.
4)由于前面的xml解析得到的是GenericBeanDefinition,而后续要用到RootBeanDefinition,所以这里需要一个转换.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
FactoryBean接口,让用户通过实现该接口定制实例化bean的逻辑.
Spring自身就提供了70多个FactoryBean的实现,它们隐藏了实例化一些复杂bean的细节,给上层应用带来了便利.
public interface FactoryBean<T> { T getObject() throws Exception; Class<?> getObjectType(); boolean isSingleton();
getObject()返回由FactoryBean创建的bean实例,如果isSingleton()返回true,则该实例会放到spring容器中单实例缓存池中.
当配置文件中<bean>的class属性配置的实现类是FactoryBean时,通过getBean()返回的不是FactoryBean本身,而是FactoryBean中getObject()方法返回的对象。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
先尝试从缓存中获取单例bean:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry { public Object getSingleton(String beanName) { //参数true设置标识允许早期依赖 return getSingleton(beanName, true); } protected Object getSingleton(String beanName, boolean allowEarlyReference) { //检查缓存中是否存在实例 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //如果为空,则锁定全局变量并进行处理 synchronized (this.singletonObjects) { //如果此bean正在加载则不处理 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) {
//调用预先设定的getObject方法. singletonObject = singletonFactory.getObject(); //记录在缓存中 this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return (singletonObject != NULL_OBJECT ? singletonObject : null); }
以上大部分操作是为了循环依赖做的.
无论是从缓存中获取的bean,还是通过不同的scope策略加载的bean都只是最原始的bean状态,并不一定是我们最终要的bean;比如,我们需要对工厂bean进行处理,那么得到的其实是工厂bean初始状态,但是我们真正需要的是工厂bean中定义的factory-method方法中返回的bean,而getObjectForBeanInstance方法就是完成这个工作的.
跟踪此方法,最终在:
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName){ //直接调用factoryBean的getObject方法 object = factory.getObject(); if(object != null && shouldPostProcess) { //调用ObjectFactory的后处理器 object = postProcessOjbectFromFactoryBean(object, beanName); } }
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { protected Object postProcessObjectFromFactoryBean(Object object, String beanName) { return applyBeanPostProcessorsAfterInitialization(object, beanName); } public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }
以上方法为调用后处理器进行处理.
在spring中有这样一条规则,尽可能保证所有的bean初始化后都会调用注册的BeanPostProcessor的postProcessAfterInitialization方法进行处理;在实际开发过程中可以设计自己的业务逻辑.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
当缓存中不存在已经加载的单例时,要从头开始加载bean:
public class DefaultSingletonBeanRegistry { protected static final Object NULL_OBJECT = new Object(); private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "'beanName' must not be null"); //全局变量需要同步 synchronized (this.singletonObjects) { //首先检查对应的bean是否已经加载过 Object singletonObject = this.singletonObjects.get(beanName); //若为空,才开始单例bean的初始化 if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while the singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { //初始化bean singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { //加入缓存 addSingleton(beanName, singletonObject); } } return (singletonObject != NULL_OBJECT ? singletonObject : null); } }
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
protected void beforeSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } }这个方法通过this.singletonCurrentlyInCreation.add(beanName)将当前正要创建的bean记录在缓存中,这样便可以对循环依赖进行检测.
singletonObject = singletonFactory.getObject();
通过调用参数的getObject()实例化bean.
protected void afterSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } }当bean加载结束后,需要移除缓存中对该bean的正在加载状态的记录.
protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT)); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } }将结果记录到缓存,并删除加载bean过程中所记录的各种辅助状态.
singletonObjects:用于保存BeanName和创建bean实例之间的关系,bean name --> bean instance
singletonFactories:用于保存BeanName和创建bean的工厂之间的关系,bean name --> ObjectFactory
earlySingletonObjects:也是保存BeanName和创建bean实例之间的关系,与singletonObjects的不同之处在于,当一个单例bean被放到这里面后,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用。
registeredSingletons:用来保存当前所有已注册的bean.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
详细分析上一步中 singletonObject = singletonFactory.getObject() 从参数中获取的过程:
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } });
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{ protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; //锁定class,根据设置的class属性或者根据className来解析class Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { //验证及准备覆盖的方法 mbdToUse.prepareMethodOverrides(); }catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //给BeanPostProcessors后处理器一个机会来返回代理来替代真正的实例 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }}
当经过前置处理之后,返回的结果若不为空,那么会直接略过后续的Bean的创建而直接返回结果。AOP功能就是基于这里判断的.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; }
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{ protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; //如尚未被解析 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }}对后处理器中,所有InstantiationAwareBeanPostProcessor类型的后处理器进行postProcessBeforeInstantiation方法和BeanPostProcessor的postProcessAfterInitialization方法的调用.
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{ protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }当程序经过以上这个方法后,bean可能已经不是我们认为的bean了,而是或许成为了一个经过处理的代理bean,可能是通过cglib生成的,也可能是通过其他技术生成的.
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{ public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }应用后处理器的postProcessAfterInitialization方法.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
若不走上面的代理创建实例,则走以下的代码创建bean实例:
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
先来看下spring对循环依赖的处理:
spring容器将每一个正在创建的bean标识符放在一个当前创建bean池中,bean标识符在创建过程中将一直保持在这个池中,因此如果在创建bean过程中发现自己已经在当前创建bean池,将抛出异常;而对于创建完的bean,将从当前创建bean池中清除掉.
1,构造器循环依赖,无法解决,抛出BeanCurrentlyInCreationException异常.
2,单例下的setter循环依赖。
通过spring容器提前暴露刚完成构造器注入但未完成其他步骤(如setter注入)的bean来完成的,通过提前暴露一个单例工厂方法ObjectFactory,从而使其他bean能引用到该bean.
3,prototype不支持循环依赖.
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //根据指定bean使用对应的策略创建新的实例,如工厂方法、构造函数自动注入,简单初始化 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } //是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖 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"); } //为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂 addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { //AOP在此将advice动态织入bean中,若没有则直接返回bean,不做任何处理 return getEarlyBeanReference(beanName, mbd, bean); } }); } Object exposedObject = bean; try { //对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,就会递归初始依赖bean populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //调用初始化方法,比如init-method 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); //earlySingletonReference只有在检测到有循环依赖的情况下才会不为空 if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { //抛异常 } } } } // Register bean as disposable. try { //根据scope注册bean registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }}
spring在实例化的时候会判断,如果有需要覆盖或者动态替换的方法则使用cglib进行动态代理,若没有则直接使用反射.
相关文章推荐
- spring笔记6 容器加载过程、bean初始化
- Spring源码深度解析(五)加载Bean
- Spring源码深度解析(五)加载Bean
- Spring源码解析笔记4——bean的加载
- Spring笔记04-Spring加载Bean
- 《Spring源码深度解析》学习笔记——bean的加载(一)
- spring学习笔记2---bean的生命周期
- Spring学习笔记之Spring的bean生命周期
- Spring IOC 学习笔记(二) BeanFactory
- 学习笔记-----JSP+Servlet+Bean的MVC
- jsf in action 笔记:bean的创建和初始化(一)(3.3 Creating and initializing beans)--2008.04.12
- Spring学习笔记之Bean的实例化
- arcgis server 9.2代码阅读笔记二:在页面上动态加载图层
- Spring配置文件加载时出现Bean property 'newscontentDAO' is not writable or has an invalid setter method错误的解决[00原创]
- J2EE学习笔记八:消息驱动bean
- Spring笔记之八(国际化,资源文件的加载)
- Spring in Action 学习笔记—第二章装配Bean
- 快速上手Spring--3. 加载Bean的配置文件
- 快速上手Spring--3. 加载Bean的配置文件
- Spring学习笔记之Bean基本管理(BeanFactory,ApplicationCo 4000 ntext)