Spring 源码粘贴5
来源:互联网 发布:淘宝wap流量是什么 编辑:程序博客网 时间:2024/05/16 01:52
懒加载与预实例化
这么说的话,有一些bean在实例化IoC容器的时候就已经实例化,而不是getBean()的时候
在refresh()中有这么一句
// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);这里处理了预实例化的bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {...// Instantiate all remaining (non-lazy-init) singletons.beanFactory.preInstantiateSingletons();}具体实现.就是调用getBean().[/呆]当然还有一个SmartInitinazingSinglton接口
public void preInstantiateSingletons() throws BeansException {if (this.logger.isDebugEnabled()) {this.logger.debug("Pre-instantiating singletons in " + this);}// 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.List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...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>() {@Overridepublic Boolean run() {return ((SmartFactoryBean<?>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}else {getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {smartSingleton.afterSingletonsInstantiated();return null;}}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}
在前面说过的doGetBean()方法里的bean(见第二篇)首先是通过createBean()然后就使用了这样的一个方法getObjectForBeanInstance()
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {...object = getObjectFromFactoryBean(factory, beanName, !synthetic);...return object;}这个方法里面就使用到FactoryBean,并使用这个FactoryBean去生成Bean实例.
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {Object object = doGetObjectFromFactoryBean(factory, beanName);...object = postProcessObjectFromFactoryBean(object, beanName);...return object;}调用doGetObjectFromFactoryBean()获取bean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException { ...object = factory.getObject();...return object;}在这里我们终于看见了熟悉的getObject()
在生成bean实例后,对这个实例进行检查,如果是FactoryBean那就获取getObject()这个方法返回的真正Bean实例
我们常用sessionFactory就是这个样子被处理的
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="c3p0ds"></property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQL57InnoDBDialect </value> </property></bean>在内部
@Overridepublic SessionFactory getObject() {return this.sessionFactory;}
@Overridepublic void afterPropertiesSet() throws IOException {...// Build SessionFactory instance.this.configuration = sfb;this.sessionFactory = buildSessionFactory(sfb);}这样,当我们使用sessionFactory的时候就已经是初始化过的了.
BeanPostProcessor Bean的后置处理器
也是在之前initializeBean()里面处理的,见第四篇 在执行初始化的前后处理postProcessBeforeInitialization()postProcessAfterInitialization()
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {...wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);...invokeInitMethods(beanName, wrappedBean, mbd);...wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);return wrappedBean;}里面的实现是一样的看一个就可以了
@Overridepublic 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;}获取到当前Bean实现的方法,并执行就可以了.这里执行到的就是Bean实现的方法了.
自动依赖装配(Autowiring)
在前面的populateBean()方法的内部有关于根据属性名字和属性类型自动装配的代码
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {...// Add property values based on autowire by name if applicable.if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}...}通过属性名字装配,获取当前Bean的(部分)属性名,然后尝试去获取一下有没有这样的Bean
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {if (containsBean(propertyName)) {Object bean = getBean(propertyName);pvs.add(propertyName, bean);registerDependentBean(propertyName, beanName);}...}我们看一下这里面的获取属性的这个方法,过滤掉了简单属性,基本类型什么的,那样是找到的太多了.
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {Set<String> result = new TreeSet<String>();PropertyValues pvs = mbd.getPropertyValues();PropertyDescriptor[] pds = bw.getPropertyDescriptors();for (PropertyDescriptor pd : pds) {if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&!BeanUtils.isSimpleProperty(pd.getPropertyType())) {result.add(pd.getName());}}return StringUtils.toStringArray(result);}
Bean的依赖检查
也是在populateBean()方法中
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {...if (needsDepCheck) {checkDependencies(beanName, mbd, filteredPds, pvs);}...}检查所有非简单属性是否已经设置好了
protected void checkDependencies(String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, PropertyValues pvs)throws UnsatisfiedDependencyException {int dependencyCheck = mbd.getDependencyCheck();for (PropertyDescriptor pd : pds) {if (pd.getWriteMethod() != null && !pvs.contains(pd.getName())) {boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType());boolean unsatisfied = (dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_ALL) ||(isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||(!isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);if (unsatisfied) {throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(),"Set this property value or disable dependency checking for this bean.");}}}}
在populateBean()方法之后的initializeBean()方法
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {...invokeAwareMethods(beanName, bean);...}调用这个方法,为bean调用一些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,如果bean实现了这些接口,IoC容器都会在正确的事件点(看下面的类说明)回调这些方法
看一个接口
public interface ApplicationContextAware extends Aware {/** * Set the ApplicationContext that this object runs in. * Normally this call will be used to initialize the object. * <p>Invoked after population of normal bean properties but before an init callback such * as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()} * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader}, * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and * {@link MessageSourceAware}, if applicable. * @param applicationContext the ApplicationContext object to be used by this object * @throws ApplicationContextException in case of context initialization errors * @throws BeansException if thrown by application context methods * @see org.springframework.beans.factory.BeanInitializationException */void setApplicationContext(ApplicationContext applicationContext) throws BeansException;}
ApplicationContextAwareProcessor是BeanPostProcessor的实现类.调用了很多的Aware的方法.来设置IoC容器的东东.
Spring是默认加载这个后置处理器的,所以当Bean实现这些Aware,在bean就可以获取这些属性了,因为已经在这里设置了.
class ApplicationContextAwareProcessor implements BeanPostProcessor {private final ConfigurableApplicationContext applicationContext;private final StringValueResolver embeddedValueResolver;/** * Create a new ApplicationContextAwareProcessor for the given context. */public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {this.applicationContext = applicationContext;this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());}@Overridepublic 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>() {@Overridepublic 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(this.embeddedValueResolver);}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);}}}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {return bean;}}
阅读全文
0 0
- Spring 源码粘贴5
- Spring 源码粘贴2
- Spring 源码粘贴3
- Spring 源码粘贴4
- Spring 源码粘贴7
- Spring 源码粘贴8
- Spring 源码粘贴10
- Spring 源码粘贴1 IoC
- Spring 源码粘贴6 AOP
- Spring 源码粘贴8-2
- Spring 源码粘贴9 MVC
- Spring 代码粘贴后感
- Spring 连接数据库的方式(粘贴)
- 在Spring中复制粘贴项目
- spring-session源码解读-5
- spring源码
- Spring源码
- Spring源码
- 【JavaScript设计模式】创建型设计模式--简单工厂、工厂方法、抽象工厂
- JVM——java 内存区域与内存溢出分析
- Erlang和其他语言的交互
- Android开发技巧
- linux笔记一
- Spring 源码粘贴5
- 打包DLL文件需要注意的东西!
- @IntDef的使用
- linux,开启PHP的oracle支持
- LAMP的配置安装
- android自学第二天 Android API Guide学习和LinearLayout布局及基本UI控件
- this用于调用重载构造函数的用法
- if语句和switch语句的区别
- 微信支付Java后台和Android的接入