本来和一个同事说每天都分享点东西的,不过最近遇到点问题,相信他也能理解
这几天也没什么心思分享什么,随便聊聊spring的ioc吧,控制反转,都不陌生,将对象的创建和依赖关系交给容器管理,具体怎么实现的,没心情说太多废话了直接说说重点吧
给出两个类
学生类
- public class Student {
- public void study(){
- System.out.println("活到老学到老");
- }
- }
学校类
- public class School {
- public Student student;
- public School(Student student) {
- super();
- this.student = student;
- }
- public void study(){
- student.study();
- }
- }
- public class School {
- @Autowired
- public Student student;
- public void study(){
- student.study();
- }
- }
这是通过注解的方式实现ioc,也可以通过xml的方法实现,注解方式简明,但是如果修改的话比较麻烦,xml形势修改起来容易,只需要把xml文件修改就可以,但是如果是复杂依赖关系的话xml文件会很臃肿
spring是如何实现ioc的,首先需要看最核心的一个接口BeanFactory
- /*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.springframework.beans.factory;
- import org.springframework.beans.BeansException;
- /**
- * The root interface for accessing a Spring bean container.
- * This is the basic client view of a bean container;
- * further interfaces such as {@link ListableBeanFactory} and
- * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
- * are available for specific purposes.
- *
- * <p>This interface is implemented by objects that hold a number of bean definitions,
- * each uniquely identified by a String name. Depending on the bean definition,
- * the factory will return either an independent instance of a contained object
- * (the Prototype design pattern), or a single shared instance (a superior
- * alternative to the Singleton design pattern, in which the instance is a
- * singleton in the scope of the factory). Which type of instance will be returned
- * depends on the bean factory configuration: the API is the same. Since Spring
- * 2.0, further scopes are available depending on the concrete application
- * context (e.g. "request" and "session" scopes in a web environment).
- *
- * <p>The point of this approach is that the BeanFactory is a central registry
- * of application components, and centralizes configuration of application
- * components (no more do individual objects need to read properties files,
- * for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and
- * Development" for a discussion of the benefits of this approach.
- *
- * <p>Note that it is generally better to rely on Dependency Injection
- * ("push" configuration) to configure application objects through setters
- * or constructors, rather than use any form of "pull" configuration like a
- * BeanFactory lookup. Spring's Dependency Injection functionality is
- * implemented using this BeanFactory interface and its subinterfaces.
- *
- * <p>Normally a BeanFactory will load bean definitions stored in a configuration
- * source (such as an XML document), and use the <code>org.springframework.beans</code>
- * package to configure the beans. However, an implementation could simply return
- * Java objects it creates as necessary directly in Java code. There are no
- * constraints on how the definitions could be stored: LDAP, RDBMS, XML,
- * properties file, etc. Implementations are encouraged to support references
- * amongst beans (Dependency Injection).
- *
- * <p>In contrast to the methods in {@link ListableBeanFactory}, all of the
- * operations in this interface will also check parent factories if this is a
- * {@link HierarchicalBeanFactory}. If a bean is not found in this factory instance,
- * the immediate parent factory will be asked. Beans in this factory instance
- * are supposed to override beans of the same name in any parent factory.
- *
- * <p>Bean factory implementations should support the standard bean lifecycle interfaces
- * as far as possible. The full set of initialization methods and their standard order is:<br>
- * 1. BeanNameAware's <code>setBeanName</code><br>
- * 2. BeanClassLoaderAware's <code>setBeanClassLoader</code><br>
- * 3. BeanFactoryAware's <code>setBeanFactory</code><br>
- * 4. ResourceLoaderAware's <code>setResourceLoader</code>
- * (only applicable when running in an application context)<br>
- * 5. ApplicationEventPublisherAware's <code>setApplicationEventPublisher</code>
- * (only applicable when running in an application context)<br>
- * 6. MessageSourceAware's <code>setMessageSource</code>
- * (only applicable when running in an application context)<br>
- * 7. ApplicationContextAware's <code>setApplicationContext</code>
- * (only applicable when running in an application context)<br>
- * 8. ServletContextAware's <code>setServletContext</code>
- * (only applicable when running in a web application context)<br>
- * 9. <code>postProcessBeforeInitialization</code> methods of BeanPostProcessors<br>
- * 10. InitializingBean's <code>afterPropertiesSet</code><br>
- * 11. a custom init-method definition<br>
- * 12. <code>postProcessAfterInitialization</code> methods of BeanPostProcessors
- *
- * <p>On shutdown of a bean factory, the following lifecycle methods apply:<br>
- * 1. DisposableBean's <code>destroy</code><br>
- * 2. a custom destroy-method definition
- *
- * @author Rod Johnson
- * @author Juergen Hoeller
- * @author Chris Beams
- * @since 13 April 2001
- * @see BeanNameAware#setBeanName
- * @see BeanClassLoaderAware#setBeanClassLoader
- * @see BeanFactoryAware#setBeanFactory
- * @see org.springframework.context.ResourceLoaderAware#setResourceLoader
- * @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
- * @see org.springframework.context.MessageSourceAware#setMessageSource
- * @see org.springframework.context.ApplicationContextAware#setApplicationContext
- * @see org.springframework.web.context.ServletContextAware#setServletContext
- * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
- * @see InitializingBean#afterPropertiesSet
- * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
- * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
- * @see DisposableBean#destroy
- * @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
- */
- public interface BeanFactory {
- /**
- * Used to dereference a {@link FactoryBean} instance and distinguish it from
- * beans <i>created</i> by the FactoryBean. For example, if the bean named
- * <code>myJndiObject</code> is a FactoryBean, getting <code>&myJndiObject</code>
- * will return the factory, not the instance returned by the factory.
- */
- String FACTORY_BEAN_PREFIX = "&";
- /**
- * Return an instance, which may be shared or independent, of the specified bean.
- * <p>This method allows a Spring BeanFactory to be used as a replacement for the
- * Singleton or Prototype design pattern. Callers may retain references to
- * returned objects in the case of Singleton beans.
- * <p>Translates aliases back to the corresponding canonical bean name.
- * Will ask the parent factory if the bean cannot be found in this factory instance.
- * @param name the name of the bean to retrieve
- * @return an instance of the bean
- * @throws NoSuchBeanDefinitionException if there is no bean definition
- * with the specified name
- * @throws BeansException if the bean could not be obtained
- */
- Object getBean(String name) throws BeansException;
- /**
- * Return an instance, which may be shared or independent, of the specified bean.
- * <p>Behaves the same as {@link #getBean(String)}, but provides a measure of type
- * safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the
- * required type. This means that ClassCastException can't be thrown on casting
- * the result correctly, as can happen with {@link #getBean(String)}.
- * <p>Translates aliases back to the corresponding canonical bean name.
- * Will ask the parent factory if the bean cannot be found in this factory instance.
- * @param name the name of the bean to retrieve
- * @param requiredType type the bean must match. Can be an interface or superclass
- * of the actual class, or <code>null</code> for any match. For example, if the value
- * is <code>Object.class</code>, this method will succeed whatever the class of the
- * returned instance.
- * @return an instance of the bean
- * @throws NoSuchBeanDefinitionException if there's no such bean definition
- * @throws BeanNotOfRequiredTypeException if the bean is not of the required type
- * @throws BeansException if the bean could not be created
- */
- <T> T getBean(String name, Class<T> requiredType) throws BeansException;
- /**
- * Return the bean instance that uniquely matches the given object type, if any.
- * @param requiredType type the bean must match; can be an interface or superclass.
- * {@code null} is disallowed.
- * <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
- * but may also be translated into a conventional by-name lookup based on the name
- * of the given type. For more extensive retrieval operations across sets of beans,
- * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
- * @return an instance of the single bean matching the required type
- * @throws NoSuchBeanDefinitionException if there is not exactly one matching bean found
- * @since 3.0
- * @see ListableBeanFactory
- */
- <T> T getBean(Class<T> requiredType) throws BeansException;
- /**
- * Return an instance, which may be shared or independent, of the specified bean.
- * <p>Allows for specifying explicit constructor arguments / factory method arguments,
- * overriding the specified default arguments (if any) in the bean definition.
- * @param name the name of the bean to retrieve
- * @param args arguments to use if creating a prototype using explicit arguments to a
- * static factory method. It is invalid to use a non-null args value in any other case.
- * @return an instance of the bean
- * @throws NoSuchBeanDefinitionException if there's no such bean definition
- * @throws BeanDefinitionStoreException if arguments have been given but
- * the affected bean isn't a prototype
- * @throws BeansException if the bean could not be created
- * @since 2.5
- */
- Object getBean(String name, Object... args) throws BeansException;
- /**
- * Does this bean factory contain a bean definition or externally registered singleton
- * instance with the given name?
- * <p>If the given name is an alias, it will be translated back to the corresponding
- * canonical bean name.
- * <p>If this factory is hierarchical, will ask any parent factory if the bean cannot
- * be found in this factory instance.
- * <p>If a bean definition or singleton instance matching the given name is found,
- * this method will return {@code true} whether the named bean definition is concrete
- * or abstract, lazy or eager, in scope or not. Therefore, note that a {@code true}
- * return value from this method does not necessarily indicate that {@link #getBean}
- * will be able to obtain an instance for the same name.
- * @param name the name of the bean to query
- * @return whether a bean with the given name is present
- */
- boolean containsBean(String name);
- /**
- * Is this bean a shared singleton? That is, will {@link #getBean} always
- * return the same instance?
- * <p>Note: This method returning <code>false</code> does not clearly indicate
- * independent instances. It indicates non-singleton instances, which may correspond
- * to a scoped bean as well. Use the {@link #isPrototype} operation to explicitly
- * check for independent instances.
- * <p>Translates aliases back to the corresponding canonical bean name.
- * Will ask the parent factory if the bean cannot be found in this factory instance.
- * @param name the name of the bean to query
- * @return whether this bean corresponds to a singleton instance
- * @throws NoSuchBeanDefinitionException if there is no bean with the given name
- * @see #getBean
- * @see #isPrototype
- */
- boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
- /**
- * Is this bean a prototype? That is, will {@link #getBean} always return
- * independent instances?
- * <p>Note: This method returning <code>false</code> does not clearly indicate
- * a singleton object. It indicates non-independent instances, which may correspond
- * to a scoped bean as well. Use the {@link #isSingleton} operation to explicitly
- * check for a shared singleton instance.
- * <p>Translates aliases back to the corresponding canonical bean name.
- * Will ask the parent factory if the bean cannot be found in this factory instance.
- * @param name the name of the bean to query
- * @return whether this bean will always deliver independent instances
- * @throws NoSuchBeanDefinitionException if there is no bean with the given name
- * @since 2.0.3
- * @see #getBean
- * @see #isSingleton
- */
- boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
- /**
- * Check whether the bean with the given name matches the specified type.
- * More specifically, check whether a {@link #getBean} call for the given name
- * would return an object that is assignable to the specified target type.
- * <p>Translates aliases back to the corresponding canonical bean name.
- * Will ask the parent factory if the bean cannot be found in this factory instance.
- * @param name the name of the bean to query
- * @param targetType the type to match against
- * @return <code>true</code> if the bean type matches,
- * <code>false</code> if it doesn't match or cannot be determined yet
- * @throws NoSuchBeanDefinitionException if there is no bean with the given name
- * @since 2.0.1
- * @see #getBean
- * @see #getType
- */
- boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
- /**
- * Determine the type of the bean with the given name. More specifically,
- * determine the type of object that {@link #getBean} would return for the given name.
- * <p>For a {@link FactoryBean}, return the type of object that the FactoryBean creates,
- * as exposed by {@link FactoryBean#getObjectType()}.
- * <p>Translates aliases back to the corresponding canonical bean name.
- * Will ask the parent factory if the bean cannot be found in this factory instance.
- * @param name the name of the bean to query
- * @return the type of the bean, or <code>null</code> if not determinable
- * @throws NoSuchBeanDefinitionException if there is no bean with the given name
- * @since 1.1.2
- * @see #getBean
- * @see #isTypeMatch
- */
- Class<?> getType(String name) throws NoSuchBeanDefinitionException;
- /**
- * Return the aliases for the given bean name, if any.
- * All of those aliases point to the same bean when used in a {@link #getBean} call.
- * <p>If the given name is an alias, the corresponding original bean name
- * and other aliases (if any) will be returned, with the original bean name
- * being the first element in the array.
- * <p>Will ask the parent factory if the bean cannot be found in this factory instance.
- * @param name the bean name to check for aliases
- * @return the aliases, or an empty array if none
- * @see #getBean
- */
- String[] getAliases(String name);
- }
很长的源码,不过可以明显可以看到有一些getBean方法,通过名字或者通过类型
工厂生产bean至少要知道两件事,1.bean的定义 2.bean之间的依赖,就如同上述的学生类和学校类之间的依赖关系
先来看第一个问题,怎么持有一个bean的定义,这里引入另一个接口BeanDefinition,看下源码
- /*
- * Copyright 2002-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.springframework.beans.factory.config;
- import org.springframework.beans.BeanMetadataElement;
- import org.springframework.beans.MutablePropertyValues;
- import org.springframework.core.AttributeAccessor;
- /**
- * A BeanDefinition describes a bean instance, which has property values,
- * constructor argument values, and further information supplied by
- * concrete implementations.
- *
- * <p>This is just a minimal interface: The main intention is to allow a
- * {@link BeanFactoryPostProcessor} such as {@link PropertyPlaceholderConfigurer}
- * to introspect and modify property values and other bean metadata.
- *
- * @author Juergen Hoeller
- * @author Rob Harrop
- * @since 19.03.2004
- * @see ConfigurableListableBeanFactory#getBeanDefinition
- * @see org.springframework.beans.factory.support.RootBeanDefinition
- * @see org.springframework.beans.factory.support.ChildBeanDefinition
- */
- public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
- /**
- * Scope identifier for the standard singleton scope: "singleton".
- * <p>Note that extended bean factories might support further scopes.
- * @see #setScope
- */
- String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
- /**
- * Scope identifier for the standard prototype scope: "prototype".
- * <p>Note that extended bean factories might support further scopes.
- * @see #setScope
- */
- String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
- /**
- * Role hint indicating that a <code>BeanDefinition</code> is a major part
- * of the application. Typically corresponds to a user-defined bean.
- */
- int ROLE_APPLICATION = 0;
- /**
- * Role hint indicating that a <code>BeanDefinition</code> is a supporting
- * part of some larger configuration, typically an outer
- * {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
- * <code>SUPPORT</code> beans are considered important enough to be aware
- * of when looking more closely at a particular
- * {@link org.springframework.beans.factory.parsing.ComponentDefinition},
- * but not when looking at the overall configuration of an application.
- */
- int ROLE_SUPPORT = 1;
- /**
- * Role hint indicating that a <code>BeanDefinition</code> is providing an
- * entirely background role and has no relevance to the end-user. This hint is
- * used when registering beans that are completely part of the internal workings
- * of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
- */
- int ROLE_INFRASTRUCTURE = 2;
- /**
- * Return the name of the parent definition of this bean definition, if any.
- */
- String getParentName();
- /**
- * Set the name of the parent definition of this bean definition, if any.
- */
- void setParentName(String parentName);
- /**
- * Return the current bean class name of this bean definition.
- * <p>Note that this does not have to be the actual class name used at runtime, in
- * case of a child definition overriding/inheriting the class name from its parent.
- * Hence, do <i>not</i> consider this to be the definitive bean type at runtime but
- * rather only use it for parsing purposes at the individual bean definition level.
- */
- String getBeanClassName();
- /**
- * Override the bean class name of this bean definition.
- * <p>The class name can be modified during bean factory post-processing,
- * typically replacing the original class name with a parsed variant of it.
- */
- void setBeanClassName(String beanClassName);
- /**
- * Return the factory bean name, if any.
- */
- String getFactoryBeanName();
- /**
- * Specify the factory bean to use, if any.
- */
- void setFactoryBeanName(String factoryBeanName);
- /**
- * Return a factory method, if any.
- */
- String getFactoryMethodName();
- /**
- * Specify a factory method, if any. This method will be invoked with
- * constructor arguments, or with no arguments if none are specified.
- * The method will be invoked on the specified factory bean, if any,
- * or otherwise as a static method on the local bean class.
- * @param factoryMethodName static factory method name,
- * or <code>null</code> if normal constructor creation should be used
- * @see #getBeanClassName()
- */
- void setFactoryMethodName(String factoryMethodName);
- /**
- * Return the name of the current target scope for this bean,
- * or <code>null</code> if not known yet.
- */
- String getScope();
- /**
- * Override the target scope of this bean, specifying a new scope name.
- * @see #SCOPE_SINGLETON
- * @see #SCOPE_PROTOTYPE
- */
- void setScope(String scope);
- /**
- * Return whether this bean should be lazily initialized, i.e. not
- * eagerly instantiated on startup. Only applicable to a singleton bean.
- */
- boolean isLazyInit();
- /**
- * Set whether this bean should be lazily initialized.
- * <p>If <code>false</code>, the bean will get instantiated on startup by bean
- * factories that perform eager initialization of singletons.
- */
- void setLazyInit(boolean lazyInit);
- /**
- * Return the bean names that this bean depends on.
- */
- String[] getDependsOn();
- /**
- * Set the names of the beans that this bean depends on being initialized.
- * The bean factory will guarantee that these beans get initialized first.
- */
- void setDependsOn(String[] dependsOn);
- /**
- * Return whether this bean is a candidate for getting autowired into some other bean.
- */
- boolean isAutowireCandidate();
- /**
- * Set whether this bean is a candidate for getting autowired into some other bean.
- */
- void setAutowireCandidate(boolean autowireCandidate);
- /**
- * Return whether this bean is a primary autowire candidate.
- * If this value is true for exactly one bean among multiple
- * matching candidates, it will serve as a tie-breaker.
- */
- boolean isPrimary();
- /**
- * Set whether this bean is a primary autowire candidate.
- * <p>If this value is true for exactly one bean among multiple
- * matching candidates, it will serve as a tie-breaker.
- */
- void setPrimary(boolean primary);
- /**
- * Return the constructor argument values for this bean.
- * <p>The returned instance can be modified during bean factory post-processing.
- * @return the ConstructorArgumentValues object (never <code>null</code>)
- */
- ConstructorArgumentValues getConstructorArgumentValues();
- /**
- * Return the property values to be applied to a new instance of the bean.
- * <p>The returned instance can be modified during bean factory post-processing.
- * @return the MutablePropertyValues object (never <code>null</code>)
- */
- MutablePropertyValues getPropertyValues();
- /**
- * Return whether this a <b>Singleton</b>, with a single, shared instance
- * returned on all calls.
- * @see #SCOPE_SINGLETON
- */
- boolean isSingleton();
- /**
- * Return whether this a <b>Prototype</b>, with an independent instance
- * returned for each call.
- * @see #SCOPE_PROTOTYPE
- */
- boolean isPrototype();
- /**
- * Return whether this bean is "abstract", that is, not meant to be instantiated.
- */
- boolean isAbstract();
- /**
- * Get the role hint for this <code>BeanDefinition</code>. The role hint
- * provides tools with an indication of the importance of a particular
- * <code>BeanDefinition</code>.
- * @see #ROLE_APPLICATION
- * @see #ROLE_INFRASTRUCTURE
- * @see #ROLE_SUPPORT
- */
- int getRole();
- /**
- * Return a human-readable description of this bean definition.
- */
- String getDescription();
- /**
- * Return a description of the resource that this bean definition
- * came from (for the purpose of showing context in case of errors).
- */
- String getResourceDescription();
- /**
- * Return the originating BeanDefinition, or <code>null</code> if none.
- * Allows for retrieving the decorated bean definition, if any.
- * <p>Note that this method returns the immediate originator. Iterate through the
- * originator chain to find the original BeanDefinition as defined by the user.
- */
- BeanDefinition getOriginatingBeanDefinition();
- }
- /**
- * Return the bean names that this bean depends on.
- */
- String[] getDependsOn();
- /**
- * Set the names of the beans that this bean depends on being initialized.
- * The bean factory will guarantee that these beans get initialized first.
- */
- void setDependsOn(String[] dependsOn);
用于设置依赖关系,到这基本可以了解了spring实现ioc需要的一些基本接口和方法了
接下来我们就要找到BeanFactory的实现类,看看它是如何生产bean的,这里就不解释怎么找到这个类的了,这个类就是DefaultListableBeanFactory,源码太长了就不贴上了,里面持有了Map<String,BeanDefinition>,可以猜想,通过这个map可以通过name获取到bean的定义和依赖关系了
我们直接写个demo
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
- <bean id="student" class="coom.michelle.dream.ioc.Student"></bean>
- </beans>
- public class Test{
- public static void main(String[] args) {
- ClassPathResource classPathResource = new ClassPathResource("beans.xml");
- DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
- XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
- xmlBeanDefinitionReader.loadBeanDefinitions(classPathResource);
- ((Student)defaultListableBeanFactory.getBean("student")).study();;
- }
- }
打印结果为
八月 03, 2017 7:26:43 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
活到老学到老
如果之前说的这些原始接口原始类都没有很深的印象,那么这个类大家肯定都知道,ApplicationContext,我们使用这个类生成bean,看下测试类
- public class Test{
- public static void main(String[] args) {
- ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:beans.xml");
- ((Student)applicationContext.getBean("student")).study();;
- }
- }
打印结果为
八月 03, 2017 7:29:22 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@b81eda8: startup date [Thu Aug 03 19:29:22 CST 2017]; root of context hierarchy
八月 03, 2017 7:29:23 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
八月 03, 2017 7:29:23 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6cd8737: defining beans [student]; root of factory hierarchy
活到老学到老
同样的效果,以上对ioc的分析就到这里结束了,希望能对朋友有所帮助,愿明天更美好