Spring容器中的Bean

Spring容器就是一个超级大工厂,Spring容器中的Bean就是该工厂的产品。
对于开发者来说,Spring框架主要是做两件事:
(1)开发Bean
(2)配置Bean

1. Bean的定义和Bean别名

bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。
它是由容器提供的配置元数据创建的。
Bean定义包含称为配置元数据的信息,需要知道:

  • 如何创建一个Bean;
  • Bean的生命周期的详细信息;
  • Bean的依赖关系。

元数据:描述数据的数据,比如表的列名,< bean>的参数等都算,都用于描述数据和对象的数据。
姓名
张三
李四
王五

2. Bean与Spring容器的关系

下图表达了Bean与Spring容器之间的关系:
在这里插入图片描述
Spring配置元数据
Spring容器完全由实际编写的配置元数据的格式解耦。有三种方法把配置元数据提供给Spring容器:

  • 基于XML的配置;
  • 基于注解的配置;
  • 基于Java的配置(配置类)。

示例1:基于XML的配置

<?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-3.0.xsd">

   <bean id="user" class="cn.zhibang.User"></bean>
   <!-- 匿名bean -->
   <bean class="cn.zhibang.User"></bean>
   <!-- 初始化时懒加载(延迟加载) -->
   <bean id="..." class="..." lazy-init="true"></bean>
   <!-- 指定Bean初始化时调用的方法 -->
   <bean id="..." class="..." init-method="..."></bean>
   <!-- 指定Bean销毁时调用的方法 -->
   <bean id="..." class="..." destroy-method="..."></bean>
</beans>

3. Bean定义中的id与name

3.1. id属性

Spring容器管理的Bean中,id是唯一标识,不能出现两个相同名称的id

<bean id="user" class="com.alibaba.model.User"></bean>

如果Spring容器管理的Bean中出现相同的id时:

  • 如果Spring是默认设置,则同名的Bean会出现后面覆盖前面的现象,且不会报异常。
  • 如果Spring设置同id不能覆盖,则会抛出异常,停止运行。

3.2. name属性

如果一个bean只配置了name属性,但没有配置ID属性,默认会是ID属性=name属性。

<bean name="user" class="com.alibaba.model.User"></bean>

这里的name=”user”相当于 id=”user” name=”user”。
注意:可以存在同名的< bean>???。

但下列情况,后面的会覆盖前面的:

<bean name="user" class="com.alibaba.model.User"></bean>
<bean id="user" class="com.alibaba.model.User"></bean>

3.3. 匿名

<bean class="com.alibaba.model.User"></bean>

未给Bean设置名称,当在使用时会报异常:
在这里插入图片描述

4.Bean作用域

在Spring定义一个bean时,可以设置scope属性来声明该bean的作用域:

<bean id="..." class="..." scope="singleton">
……
</bean>

Spring框架支持以下五个作用域:

作用域描述
singleton默认值,单例模式,在Spring IOC容器中,Bean实例将只生成一个实例。
prototype每次从容器中调用Bean时getBean(),都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean()
request每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
session同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境
global-session一般用于Portlet应用环境,改作用于仅适用于WebApplicationContext环境

5.Bean生命周期

Spring Bean的生命周期是指:
当一个bean被实例化时,它需要执行初始化方法,让bean转换成可用状态。
同样,当bean不再需要时,从容器中移除(销毁方法)。

Spring容器可以管理Singleton作用域的生命周期,Spring容器可以精确的知道该Bean何时被创建、何时被初始化完成、容器何时准备销毁该Bean实例。
对于prototype作用域的Bean,Spring容器仅仅负责创建,当创建后交给客户端代码管理,Spring容器不再跟踪其生命周期。

管理Bean的生命周期行为主要有如下两个时机:

  • 注入依赖关系之后(初始化回调)
  • 即将销毁Bean之前(销毁回调)

5.1. 注入依赖关系之后(初始化回调)

Spring提供两种方式在Bean全部属性设置成功后执行特定行为。

  • 使用init-method属性
<bean id="userBean" class="com.alibaba.model.UserBean" init-method="init"/>

类的定义:

public class UserBean {
   //初始化方法
   public void init() {
		System.out.println("实例化即执行了初始化方法...");
   }
}

当项目启动时,加截applicationContext.xml实例化一个个的Bean,当实例化UserBean时,执行init(),输出“实例化即执行了初始化方法…”

  • 实现InitializingBean接口(不建议使用)
public class ExampleBean implements InitializingBean {
   //重写方法完成初始化
   public void afterPropertiesSet() {
   }
}

5.2. 即将销毁Bean之前(销毁回调)

  • 使用destory-method属性
<bean id="userBean" class="com.alibaba.model.UserBean" destroy-method="destroy"/>

类的定义:

public class UserBean {
   public void destroy() {
      System.out.println("执行销毁的方法。。。")
   }
}
  • 实现DisposableBean接口(不建议使用)
public class UserBean implements DisposableBean {
   public void destroy() {
   }
}

5.3. 关闭hook

非Web应用序中使用Spring IOC容器,则要注册关闭hook。这样可以确保正常关闭,释放所有资源。

public static void main(String[] args) {
      AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
      context.registerShutdownHook();
}

5.4. 默认的初始化和销毁方法

如果众多Bean的初始化方法或销毁方法相同,则不需要为每个Bean配置初始化方法和销毁方法,在中配置默认初始化和销毁方法即可。

<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-3.0.xsd"
    default-init-method="init" 
    default-destroy-method="destroy">

   <bean id="..." class="..." init-method=”init” destory-method=”destroy”>
   </bean>

<bean id="..." class="..." init-method=”init” destory-method=”destroy>
   </bean>

</beans>

6. Bean后置处理器

6.1. Bean定义继承

HelloWorld类的定义:

public class HelloWorld {
   private String message1;
   private String message2;
   public void setMessage1(String message){
      this.message1  = message;
   }
   public void setMessage2(String message){
      this.message2  = message;
   }
   public void getMessage1(){
      System.out.println("World Message1 : " + message1);
   }
   public void getMessage2(){
      System.out.println("World Message2 : " + message2);
   }
}

HelloIndia类的定义:

public class HelloIndia {
   private String message1;
   private String message2;
   private String message3;
   public void setMessage1(String message){
      this.message1  = message;
   }
   public void setMessage2(String message){
      this.message2  = message;
   }
   public void setMessage3(String message){
      this.message3  = message;
   }
   public void getMessage1(){
      System.out.println("India Message1 : " + message1);
   }
   public void getMessage2(){
      System.out.println("India Message2 : " + message2);
   }
   public void getMessage3(){
      System.out.println("India Message3 : " + message3);
   }
}

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-3.0.xsd">

<bean id="helloWorld" class="com.alibaba.model.HelloWorld">
<property name="message1" value="Hello World!"/>
<property name="message2" value="Hello Second World!"/>
</bean>
<!-- 让helloIndia继承helloWorld -->
<bean id="helloIndia" class="com.alibaba.model.HelloIndia" parent="helloWorld">
<property name="message1" value="Hello India!"/>
<property name="message3" value="Namaste India!"/>
</bean>
</beans>

测试:

@Test
public void test() {
    ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
    HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
    objA.getMessage1();
    objA.getMessage2();

    HelloIndia objB = (HelloIndia) context.getBean("helloIndia");
    objB.getMessage1();
    objB.getMessage2();
    objB.getMessage3();
}

结果:

World Message1 : Hello World!
World Message2 : Hello Second World!
India Message1 : Hello India!
India Message2 : Hello Second World!
India Message3 : Namaste India!

7. 通过maven引入Spring依赖坐标

仅需在pom.xml中引入spring-context包即可。

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>

8. Spring工具插件安装(Eclipse)

Spring插件:Spring TOOL
作用:方便创建spring的xml文件
在线安装步骤:Help -> Eclipse Marketplace… -> 搜索 spring tool -> 找到后install即可。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值