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); } }
通过上面的流程,这样对象的创建就完成了。
受篇幅所限,只是介绍了对象的生成,对象的装配具体过程,下篇来写了~
相关推荐
6. **AOP代理**: Spring的IOC容器与AOP框架紧密集成,可以为Bean创建代理对象,实现切面编程,如事务管理、日志记录等。 7. **资源管理**: Spring容器还可以管理其他的资源,比如数据库连接、JMS消息等,提供统一的...
在Spring框架中,IOC具体体现在对依赖关系的管理上,使得对象的创建、依赖关系的绑定等过程不再由应用程序自身完成,而是转移到一个外部容器(IoC容器)中进行管理,这样就实现了控制权的反转。 首先,Spring IoC...
本文将通过分析并实现一个简化版的Spring IOC+MVC框架,帮助读者深入理解这两个核心概念以及Spring的工作原理。 一、Spring IOC(Inversion of Control)——控制反转 控制反转,简称IOC,是Spring框架的核心特性...
- **AOP(面向切面编程)**:Spring提供了一套完整的AOP支持,允许开发者定义拦截器,实现日志记录、事务管理等功能。 - **事件发布**:Spring容器支持事件发布和监听机制,允许bean之间进行通信,而无需直接引用...
### Spring4 Ioc-Aop 知识点详解 #### 一、Spring框架简介 Spring是一个开源框架,旨在简化企业级应用开发。通过Spring框架,普通的JavaBean能够实现以往只有通过EJB才能完成的功能。Spring的核心特性包括轻量级、...
7. **IoC(控制反转)**:Spring通过IoC管理对象的生命周期和依赖关系,对象的创建和装配由Spring容器负责,而不是由对象自身来完成,这降低了组件间的耦合度。 8. **Spring的启动**:在应用程序启动时,Spring容器...
Spring允许开发者定义切入点(Pointcuts)、切面(Advice)和其他AOP术语,然后在运行时根据这些定义动态地生成代理类,从而实现特定的关注点(如日志记录或事务管理)。 综上所述,Spring框架通过其强大的IoC和AOP...
在本文中,我们将探讨Spring IoC的基本概念、工作流程,并尝试手动实现一个简单的IoC容器。 首先,了解IoC的概念至关重要。IoC是一种设计模式,它将对象的创建和管理权从代码中分离出来,转交给一个外部容器(即IoC...
Spring的IoC容器主要有两种实现:BeanFactory和ApplicationContext。BeanFactory是最基本的容器,提供了完整的IoC功能,而ApplicationContext在此基础上增加了更多的企业级服务,如消息资源、国际化支持等。在实际...
- **方便解耦,简化开发**:Spring 通过其提供的 IOC 容器,帮助开发者实现组件间的解耦。对象之间的依赖关系由 Spring 进行管理,避免了硬编码带来的耦合问题。开发者可以更加专注于业务逻辑的实现。 - **AOP ...
Spring的核心是IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入),这些机制使得应用程序的组件之间松耦合,便于测试和维护。 标题中的"spring源码分析流程全面解析"指的是对Spring...
通过Spring的IoC容器,我们可以声明性地配置和管理这些组件,使得代码更加解耦和易于测试。同时,Spring Data JPA模块可以进一步简化与Hibernate的交互,提供更高级别的数据访问API。 当这三者结合使用时,Struts2...
此外,Spring使用了一些设计模式,如简单工厂、工厂方法和单例模式,来实现对象的创建和管理。 **Spring AOP原理与实现方式** 面向切面编程(AOP)是Spring框架的另一大特色,它允许开发者将横切关注点(如日志、...
此外,Spring的AOP特性可以方便地实现日志记录、权限控制等功能。在论坛系统中,Spring可以用来管理用户会话、实现权限控制,以及处理业务逻辑。 **Hibernate** 是一个对象关系映射(ORM)框架,它将数据库操作转化...
同时,Spring的AOP模块可以用于实现如日志记录、权限控制等通用功能。 **MyBatis框架** MyBatis是一个优秀的持久层框架,它允许开发者编写SQL语句并与Java代码进行深度融合。MyBatis消除了几乎所有的JDBC代码和参数...
2. **Spring框架**:Spring的核心是IoC(Inversion of Control,控制反转)和AOP(Aspect-Oriented Programming,面向切面编程)。IoC通过容器管理对象的依赖关系,降低了代码间的耦合度;AOP则允许我们在不修改原有...