当前位置: 首页 > 工具软件 > JFinal IOC > 使用案例 >

Spring——IOC总结

白博赡
2023-12-01

对IOC的总结

IOC是一个容器,帮我们管理所有组件

  • 依赖注入:@Autowired:自动注入某个组件要使用Spring提供的更多(IOC、AOP)必须加入到容器中;
  • 体会:容器启动,创建所有单实例bean;Autowired自动装配的时候,是从容器中找这到这个bean;
    Ioc.getBean(“bookServlet”)也是从容器中找到这个bean;容器中包含了所有的bean;
  • 调试spring的源码,容器到底是什么?其实就是一个map;
    这个map中保存所有创建好的bean,并提供外界获取功能…
    探索,单实例的bean都保存到哪个map中。
    源码测试思路:从helloworld开始,每步打上断电,进去看里面做了什么工作?翻译这个方法,放行这个方法看控制台输出。

1、Spring-IOC-AOP(动态代理);

  • AOP:代理套代理
LogAspectpRoxy{
	try{
		@Before
		method.invoke();//pjp.procced(args)
		BAspectProxy{
			@Before
			method.invoke();//pjp.procced(args)
			//XXXXXXXXXX
		}
	}catch(e){
		@AfterThrowing
	}fianlly{
		@After
	}
}

  • IOC:
    1、IOC是一个容器
    2、容器启动的时候创建所有单实例对象
    3、我们可以直接从容器中获取这个对象

2、SpringIOC:

1)、ioc容器的启动过程?启动期间都做了什么(什么时候创建所有单实例bean)
2)、ioc是如何创建这些单实例bean,并如何管理的;到底保存在那里?
思路:
从HelloWorld开始,调试每个方法的作用;
1、ClassPathXMLApplicationContext构造器

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException 
{
    super(parent);
    this.setConfigLocations(configLocations);
    if (refresh) {
//所有单实例bean创建完成
        this.refresh();转2
    }
}

2、refresh()方法

public void refresh() throws BeansException, IllegalStateException {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        this.prepareRefresh();
       //Spring解析xml配置文件将要创建的所有bean配置信息保存起来
ConfigurableListableBeanFactory 
beanFactory = this.obtainFreshBeanFactory();
        this.prepareBeanFactory(beanFactory);
        try {
            this.postProcessBeanFactory(beanFactory);
            this.invokeBeanFactoryPostProcessors(beanFactory);
            this.registerBeanPostProcessors(beanFactory);
            //支持国际化功能
this.initMessageSource();
            this.initApplicationEventMulticaster();
            //留给子类的方法
this.onRefresh();
            this.registerListeners();
//BeanFactory初始化,初始化所有单实例bean的地方
            this.finishBeanFactoryInitialization(beanFactory);转3
            this.finishRefresh();
        } catch (BeansException var9) {
           ...
} finally {
            this.resetCommonCaches();
        }
    }
}

3、finishBeanFactoryInitialization(beanFactory)方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    ...
    beanFactory.setTempClassLoader((ClassLoader)null);
    beanFactory.freezeConfiguration();
//初始化单实例类型bean
    beanFactory.preInstantiateSingletons();转4
}

4、beanFactory.preInstantiateSingletons()方法

public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isDebugEnabled()) {
        this.logger.debug("Pre-instantiating singletons in " + this);
    }
//拿到所有要创建的bean的名字
    List<String> beanNames = new ArrayList(this.beanDefinitionNames);
    Iterator var2 = beanNames.iterator();
//按顺序创建bean
    while(true) {
        while(true) {
            String beanName;
            RootBeanDefinition bd;
            do {
                do {
                    do {
                        ......
                        }

                        beanName = (String)var2.next();
//根据bean的id获取到bean的定义信息
                        bd = this.getMergedLocalBeanDefinition(beanName);
//判断bean 是单实例的,并且不是抽象的而且不是懒加载
                    } while(bd.isAbstract());
                } while(!bd.isSingleton());
            } while(bd.isLazyInit());

//是否是实现一个了FactoryBean接口的Bean
            if (this.isFactoryBean(beanName)) {
                ...
                if (isEagerInit) {
                    //创建bean的细节
this.getBean(beanName);转5
                }
            } else {
                this.getBean(beanName);
            }
        }
    }
}

5、getBean(beanName)方法

public Object getBean(String name) throws BeansException {
    return this.doGetBean(name, (Class)null, (Object[])null, false);转6
}

6、doGetBean()方法

protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
    final String beanName = this.transformedBeanName(name);
    //先从已经注册的所有单实例bean中看有没有这个bean,第一次创建bean是没有的
Object sharedInstance = this.getSingleton(beanName);
    Object bean;
......
//拿到当前bean之前需要提前创建的bean。depend-on属性;如果有就循环创建
String[] dependsOn = mbd.getDependsOn();
......
//创建bean实例
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {转7


7、getSingleton()方法

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "'beanName' must not be null");
    Map var3 = this.singletonObjects;
    synchronized(this.singletonObjects) {
          //先从一个地方将这个beanget出来
Object singletonObject = this.singletonObjects.get(beanName);
......
try {
          //利用反射创建bean
singletonObject = singletonFactory.getObject();
          newSingleton = true;
......
//添加创建的bean
......
if (newSingleton) {
         this.addSingleton(beanName, singletonObject);
      }


创建好的对象最终会保存在一个MAP中。

  • ioc容器之一:保存单实例bean的地方
  • ioc就是一个容器,单实例bean保存在map中

DefaultSingletonBeanRegistry-singletonObjects:

  • BeanFactory和ApplicationContext的区别:
  1. ApplicationContext是BeanFactory子接口;

  2. BeanFactory:bean工厂接口;负责创建bean的实例;容器里面保存的所有单例其实是一个map;Spring最底层的接口

  3. ApplicationContext:是容器接口;更多的负责容器功能的实现;(可以基于beanFactory创建好的对象之上完成强大的容器),容器可以从map中获取这个bean,并且aop,di。在ApplicationContext下的类里面。留给程序员使用的ioc容器接口。

  4. Spring里面最大的模式就是工厂模式;帮用户创建bean。

 类似资料: