spring&spring IOC

1)spring容器俯瞰

preview

                                     图片来自网络

         spring启动时,先加载bean的配置信息,读取到spring容器的Bean定义注册表中,然后根据Bean注册表实例化Bean,装配好Bean之间的依赖关系,再然后将Bean放到spring容器中,最后由应用程序读取使用。

容器加载Bean的原理

  • BeanDefinitionReader读取Resource所指向的配置文件资源,然后解析配置文件。配置文件中每一个<bean>解析成一个BeanDefinition对象,并保存到BeanDefinitionRegistry中;
  • 容器扫描BeanDefinitionRegistry中的BeanDefinition;调用InstantiationStrategy进行Bean实例化的工作;使用BeanWrapper完成Bean属性的设置工作;
  • 单例Bean缓存池:Spring 在 DefaultSingletonBeanRegistry 类中提供了一个用于缓存单实例 Bean 的缓存器,它是一个用 HashMap 实现的缓存器,单实例的 Bean 以 beanName 为键保存在这个HashMap 中。

容器启动原理:Spring应用的IOC容器通过tomcat的Servlet或Listener监听启动加载;Spring MVC的容器由DispatchServlet作为入口加载;Spring容器是Spring MVC容器的父容器

2)Spring IOC原理概述

        根据松耦合少入侵原则,new对象时与该原则在很多时候是相冲突的,并且可能一些不好的习惯导致对象不能释放。比较优的一种方式是面向接口编程。见下列

public class StudentServiceImpl {
    //class
     private  StudentDaoImpl studentDaoImpl;
     public void oldCode(){
         //原来的做法
         StudentDaoImpl=new studentDaoImpl();
         studentDaoImpl.add();
     }
 }
  //=================new====================
public class StudentServiceImpl {
     //interface
     private StudentDao StudentDaoImpl;
     public void newCode(){
         //变为面向接口编程
         StudentDaoImpl=new studentDaoImpl();
         studentDaoImpl.add();
     }
}

       比较新旧两种方式,面向接口编程的好处是显而易见的,因为当修改或者替换StudentImpl时,只需要使Student接口指向一个新的实现类即可。但是还是有弊端,当修改dao的实现类时,仍然要修改service。最好的方式就是不修改service而达到修改dao的目的。利用反射可以实现该目的:根据给出的完整类名来动态的创建对象,这种方式让类只有在生成时才决定是哪一种对象。因此可以通过假设,在某个配置文件写好了StudentDaoImpl的完全限定名称,然后通过反射来动态的创建该类。

        通过该原理,再来理解IOC就容易理解多了。spring IOC也是一个对象,在某个特定的时间创建好之后,可以实现对其他对象的控制,初始化、创建、销毁等。可以简单的理解为,只需要将要创建的类的全限定名配置好告知springIOC,他就会动态的帮我们创建对象。通过这种控制反转的设计模式(IOC)实现了松耦合,这种方式使得一个对象依赖其他对象时也会动态的关联创建出来,如service包含了dao,其依赖的dao会被自动注入进来,而不是手动创建这些类。可以把IOC看做是工厂模式的升级版,只不过对象都是在XML里面定义的,获取类名,利用反射技术,生成相应的对象。

3)spring容器装载bean

       首先在XML文件中声明类的全限定名之后,通过ClassPathXmlApplicationContext去加载,获取相应的实例调用相应的方法。也可以采用注解的方式

@Configuration
public class BeanConfiguration {

    @Bean
    public AccountDao accountDao(){
        return new AccountDaoImpl();
    }

    @Bean
    public AccountService accountService(){
        AccountServiceImpl bean=new AccountServiceImpl();
        //注入dao
        bean.setAccountDao(accountDao());
        return bean;
    }
}

使用注解@Configuration相当于XML中的<beans>标签。在该类中,每一个@Bean注解对应着一个<bean>标签。

spring依赖注入:所谓依赖注入即是,当一个bean实例引用另外一个bean实例时,spring帮助创建另外一个bean实例,并注入到当前的bean中。

4)Bean的生命周期:

  1. Bean实例的创建(getBean->createBean)
  2. 为Bean实例设置属性(populateBean)
  3. 初始化Bean(initializeBean)
  4. Bean 被应用使用
  5. 容器关闭时,Bean销毁(destoryMethod)

猜你喜欢

转载自blog.csdn.net/weixin_40018934/article/details/81097871