spring-framwork-core-ioc

 

Spring-framwork-core-IoC

 

LinkSources:https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html#beans-introduction

bean 三种实例化注册方式

  1. xml实例化bean

<?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.xsd">
  <!-- class:哪个bean需要被实例化,就用哪个bean的路径
        id:告诉spring被实例化这个bean叫什么名字-->
  <bean class="com.lin.springcore.xmlRegisterBean.Cat" id="cat"></bean>
</beans>
  1. 注解@Component实例化bean

package com.lin.springcore.annoRegisterBean;

import org.springframework.stereotype.Component;

//@Component标识这个类,需要被实例化
@Component
public class dog {
}
  1. java实例化bean

package com.lin.springcore.javaRegisterBean;

//需要被实例化的bean
public class Pig {
}
package com.lin.springcore.javaRegisterBean;

import org.springframework.context.annotation.Bean;

//注意:此处RegisterBeanConfig类上我并未使用@Configuration注解,是因为我使用的
// AnnotationConfigApplicationContext对象时,
//传递的是RegisterBeanConfig.class。否则,RegisterBeanConfig类必须也要使用xml方式
// 或@Component配置成bean。

public class RegisterBeanConfig {
  //这个注解才是真正的java实例化bean的关键,可以指定多个value值,第一个往后,为别名
  @Bean(value = {"pig", "pig2", "pig3"})
  public Pig getPig() {
      return new Pig();
  }
}
  1. Test 三种注解

    ClassPathXmlApplication和AnnotationConfigApplicationContext

    @Test
  public void test1() {
      ApplicationContext context = new ClassPathXmlApplicationContext("
      classpath:xmlRegisterBean.xml");
      Animal animal = context.getBean("Cat", Cat.class);
  }

  @Test
  public void test2() {
      ApplicationContext context = new AnnotationConfigApplicationContext(Dog.class);
      Animal animal = context.getBean(Dog.class);
  }

  @Test
  public void test3() {
      ApplicationContext context = new AnnotationConfigApplicationContext(
      RegisterBeanConfig.class);
      Object getPig1 = context.getBean("getPig");
  }

ClassPathXmlApplicationContext对象用来加载xml配置文件,AnnotationConfigApplicationContext用来加载一个类。spring通过抽象抽取了一个用户使用的对象ApplicationContext,此次ioc部分我们最常用的方法就是getBean()

ClassPathXmlApplicationContext有多个构造函数重载,这里提一种常见的ClassPathXmlApplicationContext(String... configLocations)参数接收可变长度的字符串,也就是说,ClassPathXmlApplicationContext可以同时加载多个xml配置文件。

AnnotationConfigApplicationContext也有多个构造函数重载,最常用的是AnnotationConfigApplicationContext(Class<?>... componentClasses)参数接收可变长度的Class类对象,可以同时加载多个配置对象类。

getBean()方法的可重载方式很多,接收一个字符串根据bean的id查询,接收Class根据类型查询,还可以同时接收id和class。

  1. bean注册的位置

    上边介绍的三种方式无论哪一种最终都会将pojo实例化到spring容器中。那么我们经常说的spring容器到底是什么?查看ApplicationContext对象。在spring上下文中有一个beanFactory对象,该对象实现类DefaultListableBeanFactory。依次再找父类AbstractAutowireCapableBeanFactory-->AbstractBeanFactory-->FactoryBeanRegistrySupport-->DefaultSingletonBeanRegistry中有一个Map,registeredSingletons这个Map就是用来存放所有单例模式的bean。关于bean的模式后边内容会说到。

 

 

 

  1. ApplicationContext:

    -->beanFactory

    -->DefaultListableBeanFactory

    -->AbstractAutowireCapableBeanFactory

    -->FactoryBeanRegistrySupport

    -->DefaultSingletonBeanRegistry

    -->Map

  1. 选取哪一种方式合适?

以上三种实例化bean的方式,无论使用哪一种,最终的bean都会存到到registeredSingletons这个Map中。我们可以三种方式混着用,也可以只用一种方式。使用过springmvc框架的朋友一般都有过这样的配置。

 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:applicationContext.xml</param-value>
</context-param>

ContextLoaderListener实现了ServletContextListener接口,所以能够监听Tomcat启动和停止。而在ContextLoaderListener中则读取了。classpath:applicationContext.xml。在这个xml中我们是不是了实例化bean,例如dataSource。

而使用springboot的朋友一般极少使用xml实例化的方式,就算有需要配置的也会在application.properties中配置。如果是我们用户自己的pojo,那使用注解方式实例化bean最方便,如果有一些系统pojo需要统一规范的配置,那就选取xml方式实例化bean,便于管理和修改,而且不容易配破坏,大家都不会随便修改xml的内容嘛。最后如果你使用的是第三方的jar,那此时使用java的实例化方式是最合适的了,毕竟你也无法在源码上加@Component注解。

posted @ 2019-12-24 19:18  凌林的芳香  阅读(169)  评论(0编辑  收藏  举报