深入理解Spring|深入理解Spring IOC容器

本文将从纯xml模式、xml和注解结合、纯注解的方式讲解Spring IOC容器的配置和相关应用。
纯XML模式
实例化Bean的三种方式:

  1. 使用无参构造函数
默认情况下,会使用反射调用无参构造函数来创建对象。

  1. 使用静态方法创建
在实际开发中,我们使用的方法有时候不是通过构造函数创建出来的,他可能在创建的时候会做很多额外的操作。此时会提供一个创建对象的方法,如果这个方法是static修饰的,就是用这种配置方式。

  1. 使用实例化方法创建
当方法不是静态的时候,用这种方式

bean的作用范围和声明周期
深入理解Spring|深入理解Spring IOC容器
文章图片

常用的是singleton【默认】(单例模式)和prototype(原型模式或多例模式)。通过scope属性可以进行配置

不同作用范围的生命周期
单例模式:singleton
对象创建:当创建容器时,对象就被创建
对象活着:只要容器在,对象一直活着
对象死亡:当容器销毁,对象就被销毁
总结:单例模式的bean对象生命周期与容器相同
多例模式:prototype
对象创建:当使用对象时,创建新的对象实例
对象活着:只要对象在使用中,就一直活着
对象死亡:当对象长时间不用时,被垃圾回收器回收
总结:多例模式的bean对象,spring框架只负责创建,不负责销毁。
Bean的标签属性
  • id属性: ?于给bean提供?个唯?标识。在?个标签内部,标识必须唯?。
  • class属性:?于指定创建Bean对象的全限定类名。
  • name属性:?于给bean提供?个或多个名称。多个名称?空格分隔。
  • factory-bean属性:?于指定创建当前bean对象的??bean的唯?标识。当指定了此属性之后,
    class属性失效。
  • factory-method属性:?于指定创建当前bean对象的???法,如配合factory-bean属性使?,
    则class属性失效。如配合class属性使?,则?法必须是static的。
  • scope属性:?于指定bean对象的作?范围。通常情况下就是singleton。当要?到多例模式时,
    可以配置为prototype。
  • init-method属性:?于指定bean对象的初始化?法,此?法会在bean对象装配后调?。必须是
    ?个?参?法。
  • destory-method属性:?于指定bean对象的销毁?法,此?法会在bean对象销毁前执?。它只
    能为scope是singleton时起作?。
DI依赖注入
  1. 按照注入的方式分类
  • 构造函数注入:就是利用带参构造函数实现对类成员的属性赋值

  • set方法注入:通过类成员的set方法实现数据注入

  1. 按照注入的数据类型分类
  • 基本数据类型和String
  • 其他Bean类型
  • 复杂类型(集合类型)
基本类型使用value,其他bean类型使用ref,复杂类型使用对应的array、map、set标签
aa bb

web.xml
Archetype Created Web ApplicationcontextConfigLocationclasspath:applicationContext.xml org.springframework.web.context.ContextLoaderListener

xml与注解结合的方式
注意:实际开发中,纯xml模式使用已经很少了,引入注解功能,不需要引入额外的jar包。xml+注解结合模式中,xml文件依然存在,所以Spring IOC容器的启动仍然从加载xml开始。
一般来说第三方jar包里面的bean定义在xml里面,自己开发的bean使用注解。
将第三方jar包的bean放入容器

xml中标签与注解的对应
xml形式 注解
标签 @Component,注解加在类上。默认情况下bean的id为类名(首字母小写)。另外,针对分层代码开发提供了@Componenet的三种别名@Controller、
@Service、@Repository分别?于控制层类、服务层类、dao层类的bean定义,这
四个注解的?法完全?样,只是为了更清晰的区分?已
标签的scope属性 | @Scope("prototype")
DI依赖注入的注解实现方式
  1. @Autowired(推荐使用)
@Autowired为Spring提供的注解。策略是按类型注入
public class TransferServiceImpl implements TransferService {@Autowired private AccountDao accountDao; }

如上代码所示,这样装配会去spring容器中找到类型为AccountDao的bean,然后将其中如。但如果一个类型有多个bean怎么办呢?可以配合@Qualifier("bean的id")使用。
public class TransferServiceImpl implements TransferService {@Autowired @Qualifier("jdbcAccountDao") private AccountDao accountDao; }

  1. @Resource
@Resource注解由j2EE提,如果指定了name或type就会根据指定的来,如果都没有指定就自动按照ByName方式装配
注意:@Resource在Jdk11中已经移除,如果要使用,需要单独引入jar包。
javax.annotation javax.annotation-api 1.3.2

在Servlet类里面获取applicationContext
public class TransferServlet extends HttpServlet {@Override public void init() throws ServletException { WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); ProxyFactory proxyFactory = (ProxyFactory) webApplicationContext.getBean("proxyFactory"); transferService= (TransferService) proxyFactory.getJdkProxy(webApplicationContext.getBean("transferService")); } }

纯注解模式
将xml配置改为java代码:
在配置类上声明@Configuration,表明是配置类。
@Configuration @ComponentScan("com.mmc.ioc") @PropertySource("classpath:jdbc.properties") public class SpringConfig {@Value("${jdbc.driver}") private String driverClass; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean public DataSource dataSource(){ DruidDataSource druidDataSource=new DruidDataSource(); druidDataSource.setDriverClassName(driverClass); druidDataSource.setUrl(url); druidDataSource.setUsername(username); druidDataSource.setPassword(password); return druidDataSource; } }

如果还有其他配置类,可以通过@Import引入进来。
web.xml配置如下:
Archetype Created Web ApplicationcontextClass【深入理解Spring|深入理解Spring IOC容器】org.springframework.web.context.support.AnnotationConfigWebApplicationContext contextConfigLocationcom.mmc.ioc.SpringConfig org.springframework.web.context.ContextLoaderListener

高频面试题:
BeanFactory、FactoryBean、ApplicationContext的区别
  • BeanFactory是Spring框架中IOC容器的顶层接口,它只是用来定义一些基础功能
  • ApplicationContext是它的一个子接口,它拥有更多的功能,如国际化支持和资源访问等等。
  • FactoryBean:一般情况下,Spring通过反射机制实例化Bean,在某些情况下,实例化bean过程比较复杂,这时配置起来就比较麻烦。如果采用编码的方式会简单一些。于是Spring给我们提供了FactoryBean的接口,用户就可以通过实现这个接口来自定义实例化Bean的逻辑。
总结:BeanFactory是负责生产和管理Bean的一个工厂接口,提供一个Spring Ioc容器规范。FactoryBean是一种Bean创建的方法,对Bean的一种扩展。
类图如下:
深入理解Spring|深入理解Spring IOC容器
文章图片

    推荐阅读