IOC: Inversion of Control, 指由spring容器来生成对象并且完成对象的装配。
下面来看下这两个问题:(下面是以 ClassPathXmlApplicationContext为起点)
1, spring如何生成对象?
2, spring如何完成对象组装?
完成这个的核心是通过BeanFactory,下面是BeanFactory的代码:
public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException; Class<?> getType(String name) throws NoSuchBeanDefinitionException; String[] getAliases(String name); }
从上面可知,如果有了BeanFactory,就可以通过getBean的方法去获取想要的对象,后面组装的事情也就顺理成章了。
下面是简单的spring的demo,代码可以通过附件下载,部分测试代码如下:
public class SpringDemo { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:/beans.xml"); AppleService appleService = context.getBean("appleService", AppleService.class); Apple apple = appleService.createApple(); System.out.println(apple); } }
代码的入口从ClassPathXmlApplicationContext开始,下面是ClassPathXmlApplicationContext的代码:
public ClassPathXmlApplicationContext(String[] paths, Class clazz, ApplicationContext parent) throws BeansException { super(parent); Assert.notNull(paths, "Path array must not be null"); Assert.notNull(clazz, "Class argument must not be null"); this.configResources = new Resource[paths.length]; for (int i = 0; i < paths.length; i++) { this.configResources[i] = new ClassPathResource(paths[i], clazz); } refresh(); }
调用父类AbstractApplicationContext的refresh方法,
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } } }
在obtainFreshBeanFactory方法中,创建DefaultListableBeanFactory,然后通过DocumentBuilderFactory将spring配置文件转成Document对象,然后根据不同的节点名进行处理,解析元素代码如下:
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { //IMPORT_ELEMENT = "import" if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } //ALIAS_ELEMENT = "alias" else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } //BEAN_ELEMENT="bean" else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } //NESTED_BEANS_ELEMENT = "beans" else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } }
以bean节点解析为例,看下parseBeanDefinitionElement的方法
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //解析bean节点 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // Register the final decorated instance. //将BeanDefinition注册到BeanFactory中(后面有解释) BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
下面是调用BeanDefinitionParserDelegate的parseBeanDefinitionAttributes方法,将xml配置的bean的属性(lazy-init, scope, destroy-method等属性)设置到BeanDefinition中。
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd) { if (ele.hasAttribute(SCOPE_ATTRIBUTE)) { // Spring 2.x "scope" attribute bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE)); if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { error("Specify either 'scope' or 'singleton', not both", ele); } } else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { // Spring 1.x "singleton" attribute bd.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ? BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE); } else if (containingBean != null) { // Take default from containing bean in case of an inner bean definition. bd.setScope(containingBean.getScope()); } if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) { bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE))); } String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE); if (DEFAULT_VALUE.equals(lazyInit)) { lazyInit = this.defaults.getLazyInit(); } bd.setLazyInit(TRUE_VALUE.equals(lazyInit)); String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE); bd.setAutowireMode(getAutowireMode(autowire)); String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE); bd.setDependencyCheck(getDependencyCheck(dependencyCheck)); if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) { String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE); bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS)); } String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE); if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) { String candidatePattern = this.defaults.getAutowireCandidates(); if (candidatePattern != null) { String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern); bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName)); } } else { bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate)); } if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) { bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE))); } if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) { String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE); if (!"".equals(initMethodName)) { bd.setInitMethodName(initMethodName); } } else { if (this.defaults.getInitMethod() != null) { bd.setInitMethodName(this.defaults.getInitMethod()); bd.setEnforceInitMethod(false); } } if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) { String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE); if (!"".equals(destroyMethodName)) { bd.setDestroyMethodName(destroyMethodName); } } else { if (this.defaults.getDestroyMethod() != null) { bd.setDestroyMethodName(this.defaults.getDestroyMethod()); bd.setEnforceDestroyMethod(false); } } if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) { bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE)); } if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) { bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE)); } return bd; }
在上面的processBeanDefinition方法中,解析完某个节点,生成BeanDefinition时,会调用BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())方法,然后向BeanFactory注册该BeanDefinition对象,代码如下:
//DefaultListableBeanFactory.java public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { ... synchronized (this.beanDefinitionMap) { Object oldBeanDefinition = this.beanDefinitionMap.get(beanName); if (oldBeanDefinition != null) { if (!this.allowBeanDefinitionOverriding) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } } else { this.beanDefinitionNames.add(beanName); this.frozenBeanDefinitionNames = null; } this.beanDefinitionMap.put(beanName, beanDefinition); } resetBeanDefinition(beanName); }
然后重新回到AbstractApplicationContext的refresh方法,调用invokeBeanFactoryPostProcessors(spring提供了BeanFactoryPostProcessor扩展点,可以通过实现BeanFactoryPostProcess来初始化某些参数),再通过调用refresh方法中的finishBeanFactoryInitialization来完成对象的创建。代码如下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. 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(); // Instantiate all remaining (non-lazy-init) singletons. //创建并且组装对象 beanFactory.preInstantiateSingletons(); }
然后进入DefaultListableBeanFactory的preInstantiateSingletons方法,代码如下,beanDefinitionMap存放的是前面解析配置文件得到的<beanName, BeanDefinition>的map数据。
public void preInstantiateSingletons() throws BeansException { ... 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 { getBean(beanName); } } } }
在getBean方法中,会调用AbstractBeanFactory的doGetBean来创建对象,方法如下:
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { ... if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } ... return (T) bean; }
在createBean中,会调用AbstractAutowireCapableBeanFactory的doCreateBean方法,代码如下:(这个方法显示了对象的创建以及后续初始化的流程)
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) { //调用BeanPostProcessor处理 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() { public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { //设置bean的参数(通过property标签配置) 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); } } ... return exposedObject; }
继续往下看createBeanInstance方法,通过调用instantiateBean实例化对象,代码如下:
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { return getInstantiationStrategy().instantiate(mbd, beanName, parent); } }, getAccessControlContext()); } else { beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } }
InstantiationStrategy有两种,SimpleInstantiationStrategy和CglibSubclassingInstantiationStrategy。关系如下:
spring对CglibSubclassingInstantiationStrategy的使用场景注释:Using Method Injection features requires CGLIB on the classpath. However, the core IoC container will still run without CGLIB being available.
下面再来看SimpleInstantiationStrategy的instantiate方法,代码如下:
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. if (beanDefinition.getMethodOverrides().isEmpty()) { Constructor<?> constructorToUse; synchronized (beanDefinition.constructorArgumentLock) { constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class clazz = beanDefinition.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() { public Constructor run() throws Exception { return clazz.getDeclaredConstructor((Class[]) null); } }); } else { constructorToUse = clazz.getDeclaredConstructor((Class[]) null); } beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Exception ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } return BeanUtils.instantiateClass(constructorToUse); } else { // Must generate CGLIB subclass. return instantiateWithMethodInjection(beanDefinition, beanName, owner); } }
通过上面的流程,这样对象的创建就完成了。
受篇幅所限,只是介绍了对象的生成,对象的装配具体过程,下篇来写了~
相关推荐
Java SSM项目是一种使用Java语言和SSM框架(Spring + Spring MVC + MyBatis)开发的Web应用程序。SSM是一种常用的Java开发框架组合,它结合了Spring框架、Spring MVC框架和MyBatis框架的优点,能够快速构建可靠、...
因为 org.springframework.beans.factory.BeanFactory 是一个简单接口,所以可以针对各种底层存储方法实现。最常用的 BeanFactory 定义是 XmlBeanFactory,它根据 XML 文件中的定义装入 bean,如清单 1 所示。 清单...
Spring框架: 负责依赖注入、AOP编程等,提供了控制反转(IoC)和面向切面编程(AOP)的支持。 Spring MVC框架: 负责请求响应和路由管理,使得项目具有良好的MVC架构。 Hibernate框架: 负责对象关系映射(ORM),...
Spring作为IoC容器,负责管理对象的生命周期和依赖关系,使得系统的各个模块能够灵活地组合和替换。该系统的主要功能包括:车辆信息的增删改查,包括车辆的类型、车牌号、颜色、购买日期等;用户信息的增删改查,...
一、项目背景与目标 随着城市化的快速发展,车辆数量急剧增加,车位租赁成为了一个迫切的需求。...Spring提供IoC和AOP功能,简化企业级应用开发流程;SpringMVC基于MVC设计模式,实现Web应用的快速开发;
利用Spring框架实现了控制反转(IoC)和依赖注入,提高了代码的可维护性和可测试性。 使用Spring MVC实现了前端请求的分发和处理,将业务逻辑与视图层进行了有效分离,提高了系统的可扩展性。 结合Spring Data JPA...
基于微信小程序的小说阅读器结合SSM(Spring + Spring MVC + MyBatis)框架的实现,为用户提供了便捷的在线小说阅读服务,具有以下特点: 微信小程序端: 用户友好的界面设计,符合微信小程序的交互规范,提供流畅...
使用Spring框架实现控制反转(IoC)和面向切面编程(AOP),提高了代码的可维护性和可测试性。 使用Spring MVC实现了前端请求的分发和处理,将业务逻辑与视图层进行了有效分离。 结合MyBatis框架实现了持久层与...
“weixin135房屋租赁管理系统”的设计与实现基于SSM(Spring, Spring MVC, MyBatis)框架,这是一个典型的Java EE应用架构。SSM集成了Spring的依赖注入和面向切面编程、Spring MVC的MVC框架以及MyBatis的持久层框架...
该系统采用SSM(Spring, SpringMVC, MyBatis)框架进行设计与实现,结合微信平台强大的用户基础和操作便利性,为学生提供了一个快速、简单的报修通道。 使用的技术主要包括: 微信小程序前端开发:利用微信官方...
说明文档详细记录了系统的功能设计、数据库结构、关键代码实现以及可能遇到的问题和解决方案,为二次开发或定制提供了有力的指导。 总的来说,这份资源不仅是一份优秀的毕业设计作品,更是一份实用的学习资料和开发...
Spring框架提供了强大的IoC(控制反转)和AOP(面向切面编程)功能,简化了系统的配置和开发过程。SpringMVC作为一个基于MVC(模型-视图-控制器)设计模式的框架,提供了良好的请求分发和处理机制。MyBatis作为一个...
Spring框架提供了IoC(控制反转)和AOP(面向切面编程)等功能,简化了系统的开发和配置。SpringMVC作为一个基于MVC(模型-视图-控制器)的框架,提供了良好的请求处理和页面跳转机制。MyBatis作为一个优秀的持久层...
Spring框架提供了IoC(控制反转)和AOP(面向切面编程)等功能,简化了系统的开发和配置。SpringMVC作为一个基于MVC(模型-视图-控制器)的框架,提供了良好的请求处理和页面跳转机制。MyBatis作为一个优秀的持久层...
Spring框架提供了IoC(控制反转)和AOP(面向切面编程)等功能,简化了系统的开发和配置。SpringMVC作为一个基于MVC(模型-视图-控制器)的框架,提供了良好的请求处理和页面跳转机制。MyBatis作为一个优秀的持久层...
Spring框架提供了IoC(控制反转)和AOP(面向切面编程)等功能,简化了系统的开发和配置。SpringMVC作为一个基于MVC(模型-视图-控制器)的框架,提供了良好的请求处理和页面跳转机制。MyBatis作为一个优秀的持久层...
Spring框架提供了IoC(控制反转)和AOP(面向切面编程)等功能,简化了系统的开发和配置。SpringMVC作为一个基于MVC(模型-视图-控制器)的框架,提供了良好的请求处理和页面跳转机制。MyBatis作为一个优秀的持久层...
系统的后端采用SSM框架,Spring框架提供了IoC(控制反转)和AOP(面向切面编程)等功能,简化了系统的开发和配置。SpringMVC作为一个基于MVC(模型-视图-控制器)的框架,提供了良好的请求处理和页面跳转机制。...
Spring框架提供了IoC(控制反转)和AOP(面向切面编程)等功能,简化了系统的开发和配置。SpringMVC作为一个基于MVC(模型-视图-控制器)的框架,提供了良好的请求处理和页面跳转机制。MyBatis作为一个优秀的持久层...