2021-04-09

Spring

Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益

优点

◆JAVA EE应该更加容易使用。

◆面向对象的设计比任何实现技术(比如JAVA EE)都重要。

◆面向接口bia,而不是针对类编程。Spring将使用接口的复杂度降低到零。(面向接口编程有哪些复杂度?)

◆代码应该易于测试。Spring框架会帮助你,使代码的测试更加简单。

◆JavaBean提供了应用程序配置的最好方法。

◆在Java中,已检查异常(Checked exception)被过度使用。框架不应该迫使你捕获不能恢复的异常。

Spring DI(依赖注入)的实现方式:属性注入和构造注入

依赖注入(Dependency Injection,DI)和控制反转含义相同,它们是从两个角度描述的同一个概念。
当某个 Java 实例需要另一个 Java 实例时,传统的方法是由调用者创建被调用者的实例(例如,使用 new 关键字获得被调用者实例),而使用 Spring 框架后,被调用者的实例不再由调用者创建,而是由 Spring 容器创建,这称为控制反转。
Spring 容器在创建被调用者的实例时,会自动将调用者需要的对象实例注入给调用者,这样,调用者通过 Spring 容器获得被调用者实例,这称为依赖注入。

被调用者

public  class  Person{

}

调用者

public class  Student{
    //被调用者---依赖对象
    private  Person  person;
    public  void  getPerson(){
        person=new Person();
    }
}

当某个 Java 实例【Student】需要另一个 Java 实例【Person】,Spring 容器在创建被调用者的实例【Person】时会自动将调用者需要的对象实例【Person】注入给调用者【Student】,这样调用者【Student】通过 Spring 容器获得被调用者【Person】实例,这称为依赖注入。
依赖注入主要有两种实现方式,分别是属性 setter 注入构造方法注入。具体介绍如下。

1)属性 setter 注入--Set方法注入

指 IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 bean 后,调用该 bean 的 setter 方法,即可实现基于 setter 的 DI。

1. 创建项目,完善结构,导入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

2. 创建被调用者类

package com.wangxing.springdemo2;
public class Person {
    public  void testPerson(){
        System.out.println( "Person类的实例方法testPerson()" );
    }
}

3. 创建调用者类

package com.wangxing.springdemo2;
public class Student {
    //定义依赖对象
    private Person  person;
    //依赖对象的set方法
    public void setPerson(Person person) {
        this.person = person;
    }
    public void getStudent(){
        System.out.println("Student类的实例方法getStudent()");
        person.testPerson();
    }
}

4. 配置Spring配置文件

<?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">
    <!--创建Person类对象-->
    <bean id="per" class="com.wangxing.springdemo2.Person"></bean>
    <!--创建Student类对象-->
    <bean id="student" class="com.wangxing.springdemo2.Student">
        <!--setter注入-->
        <property name="person" ref="per"></property>
    </bean>
</beans>

5. 创建单元测试

package com.wangxing.Testa;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
    @Test
    public void test1(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student=applicationContext.getBean("Student",Student.class);
        student.getStudent();
    }
}

2)构造方法注入

指 IoC 容器使用构造方法注入被依赖的实例。基于构造器的 DI 通过调用带参数的构造方法实现,每个参数代表一个依赖。

1. 创建项目,完善结构,导入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

2. 创建被调用者类

package com.wangxing.springdemo2;
public class Person {
    public  void testPerson(){
        System.out.println( "Person类的实例方法testPerson()" );
    }
}

3. 创建调用者类

package com.wangxing.springtest3;
public class Student {
    //定义依赖对象
    private Person  person;
    //定义有参数的构造方法
    public Student(Person  person){
        this.person=person;
    }
    public void getStudent(){
        System.out.println("Student类的实例方法getStudent()");
        person.testPerson();
    }
}

4. 创建spring配置文件

<?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">
    <!--创建Person类对象-->
    <bean id="per" class="com.wangxing.springtest3.Person"></bean>
    <!--创建Student类对象-->
    <bean id="stu" class="com.wangxing.springtest3.Student">
        <!--构造方法注入-->
        <constructor-arg index="0" ref="per"></constructor-arg>
    </bean>
</beans>

5. 创建测试方法

package com.wangxing.testb;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
    @Test
    public void test1(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student=applicationContext.getBean("stu",Student.class);
        student.getStudent();
    }
}

Spring Bean的配置及常用属性

作为 Spring 核心机制的依赖注入,改变了传统的编程习惯,对组件的实例化不再由应用程序完成,转而交由 Spring 容器完成,在需要时注入应用程序中,从而对组件之间依赖关系进行了解耦。这一切都离不开 Spring 配置文件中使用的 <bean> 元素。
Spring 容器可以被看作一个大工厂,而 Spring 容器中的 Bean 就相当于该工厂的产品。如果希望这个大工厂能够生产和管理 Bean,这时则需要告诉容器需要哪些 Bean,以及需要以何种方式将这些 Bean 装配到一起。
Spring 配置文件支持两种不同的格式,分别是 XML 文件格式和 Properties 文件格式。
通常情况下,Spring 会以 XML 文件格式作为 Spring 的配置文件,这种配置方式通过 XML 文件注册并管理 Bean 之间的依赖关系。
XML 格式配置文件的根元素是 <beans>,该元素包含了多个 <bean> 子元素,每一个 <bean> 子元素定义了一个 Bean,并描述了该 Bean 如何被装配到 Spring 容器中。

定义 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">
    <!--创建Person类对象-->
    <bean  name="per" class="com.wangxing.springtest3.Person"></bean>
    <!--创建Student类对象-->
    <bean id="stu" class="com.wangxing.springtest3.Student">
        <!--构造方法注入-->
        <constructor-arg index="0" ref="per"></constructor-arg>
    </bean>
</beans>

在上述代码中,分别使用 id 和 name 属性定义了两个 Bean,并使用 class 元素指定了 Bean 对应的实现类。
<bean> 元素中包含很多属性,其常用属性如表 1 所示。

表 1 <bean>元素的常用属性

属性名称

描述

id

是一个 Bean 的唯一标识符,Spring 容器对 Bean 的配置和管理都通过该属性完成

name

Spring 容器同样可以通过此属性对容器中的 Bean 进行配置和管理,name 属性中可以为 Bean 指定多个名称,每个名称之间用逗号或分号隔开

class

该属性指定了 Bean 的具体实现类,它必须是一个完整的类名,使用类的全限定名【反射机制】

scope 

用于设定 Bean 实例的作用域,其属性值有 singleton(单例)、prototype(原型)、request、session 和 global Session。其默认值是 singleton

constructor-arg

<bean>元素的子元素,可以使用此元素传入构造参数进行实例化。该元素的 index 属性指定构造参数的序号(从 0 开始),type 属性指定构造参数的类型

property

<bean>元素的子元素,用于调用 Bean 实例中的 Set 方法完成属性赋值,从而完成依赖注入。该元素的 name 属性指定 Bean 实例中的相应属性名

ref

<property> 和 <constructor-arg> 等元素的子元索,该元素中的 bean 属性用于指定对 Bean 工厂中某个 Bean 实例的引用

value

<property> 和 <constractor-arg> 等元素的子元素,用于直接指定一个常量值

list

用于封装 List 或数组类型的依赖注入

set

用于封装 Set 类型属性的依赖注入

map

用于封装 Map 类型属性的依赖注入

entry

<map> 元素的子元素,用于设置一个键值对。其 key 属性指定字符串类型的键值,ref 或 value 子元素指定其值

Spring实例化Bean的三种方法

在面向对象的程序中,要想调用某个类的成员方法,就需要先实例化该类的对象。在 Spring 中,实例化 Bean 有三种方式,分别是构造器实例化、静态工厂方式实例化和实例工厂方式实例化。本节将针对这三种方式分别进行讲解。

构造器实例化

构造器实例化是指 Spring 容器通过 Bean 对应的类中默认的构造函数实例化 Bean。下面通过案例演示如何使用构造器实例化 Bean。

1. 创建项目,完善结构,导入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

2. 创建Person类

package com.wangxing.springdemo3.create1;
public class Person {
    public  void testPerson() {
        System.out.println( "Person类的testPerson()实例方法" );
    }
}

3. 创建Spring配置文件

<?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">
    <bean id="person" class="com.wangxing.springdemo3.create1.Person"></bean>
</beans>

4. 测试方法

@Test
public void test1(){
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    Person person = context.getBean("person",Person.class);
    person.testPerson();
}

静态工厂方式实例化

在 Spring 中,也可以使用静态工厂的方式实例化 Bean。此种方式需要提供一个静态工厂方法创建 Bean 的实例。

1. 创建项目,完善结构,导入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

2. 创建UserBean

package com.wangxing.springdemo3.create2;
public class UserBean {
    public  void testUser() {
        System.out.println( "UserBean类的testUser()实例方法" );
    }
}

3. 创建静态工厂类并在该静态工厂类中创建一个返回UserBean类对象的名为getUserBean的静态方法,用于创建 Bean 的实例,如下所示。

package com.wangxing.springdemo3.create2;
/**
 * 静态工厂类
 */
public class MyBeanStaticFactory {
    //4.创建一个返回UserBean类对象的名为getUserBean的静态方法
    public  static  UserBean getUserBean(){
        return  new UserBean();
    }
}

4. 创建 Spring 配置文件

<?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">
    <bean id="user" class="com.wangxing.springdemo3.create2.MyBeanStaticFactory" factory-method="getUserBean"></bean>
</beans>

上述代码中,定义了一个 id 为 user的 Bean,其中 class 属性指定了其对应的工厂实现类为 MyBeanStaticFactory,而 factory-method 属性用于告诉 Spring 容器调用工厂类中的 getUserBean()方法获取 Bean 的实例。

5. 创建测试类

@Test
public void test1(){
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    UserBean userBean = context.getBean("user",UserBean.class);
    userBean.testUser();
}

实例工厂方式实例化

在 Spring 中,还有一种实例化 Bean 的方式就是采用实例工厂。在这种方式中,工厂类不再使用静态方法创建 Bean 的实例,而是直接在成员方法中创建 Bean 的实例。
同时,在配置文件中,需要实例化的 Bean 也不是通过 class 属性直接指向其实例化的类,而是通过 factory-bean 属性配置一个实例工厂,然后使用 factory-method 属性确定使用工厂中的哪个方法。下面通过案例演示实例工厂方式的使用。

1. 创建项目,完善结构,导入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

2. 创建Student类

package com.wangxing.springdemo3.create3;
public class Student {
    public void testStudent(){
        System.out.println("Student类的testStudent()实例方法");
    }
}

3. 创建一个名为 MyBeanFactory 的实例工厂类,在该类中创建一个返回Student类对象的实例方法。

package com.wangxing.springdemo3.create3;
/**
 * 实例工厂类
 */
public class MyBeanFactory {
    //返回Student类对象的实例方法
    public Student getStudent(){
        return new Student();
    }
}

4. 创建 Spring 配置文件

<?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">
    <!--创建实例工厂类对象-->
    <bean id="myBeanFactory" class="com.wangxing.springdemo3.create3.MyBeanFactory"></bean>
    <!--创建Student类对象-->
    <bean id="student" factory-bean="myBeanFactory" factory-method="getStudent"></bean>
</beans>

上述代码中,首先配置了一个实例工厂 BeanmyBeanFactory,然后配置了需要实例化的 Bean。在 id 为 student的 Bean 中,使用 factory-bean 属性指定一个实例工厂,该属性值就是实例工厂的 id 属性值。使用 factory-method 属性确定使用工厂中的 getStudent() 方法。

5. 创建测试类

@Test
public void test1(){
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student = context.getBean("student",Student.class);
    student.testStudent();
}

Spring中Bean的作用域

本节先简单介绍了 Spring 中 bean 的 5 种作用域,然后详细介绍 singleton 和 prototype 这两种最常用的作用域。

作用域的种类

Spring 容器在初始化一个 Bean 的实例时,同时会指定该实例的作用域。Spring3 为 Bean 定义了五种作用域,具体如下。

1)singleton

单例模式,使用 singleton 定义的 Bean 在 Spring 容器中只有一个实例,这也是 Bean 默认的作用域。

2)prototype

原型模式,每次通过 Spring 容器获取 prototype 定义的 Bean 时,容器都将创建一个新的 Bean 实例。

3)request

在一次 HTTP 请求中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Request 内有效。

4)session

在一次 HTTP Session 中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Session 内有效。

5)global Session

在一个全局的 HTTP Session 中,容器会返回该 Bean 的同一个实例。该作用域仅在使用 portlet context 时有效。
在上述五种作用域中,singleton 和 prototype 是最常用的两种,接下来将对这两种作用域进行详细讲解。

singleton 作用域

singleton 是 Spring 容器默认的作用域,当一个 Bean 的作用域为 singleton 时,Spring 容器中只会存在一个共享的 Bean 实例,并且所有对 Bean 的请求,只要 id 与该 Bean 定义相匹配,就只会返回 Bean 的同一个实例。
通常情况下,这种单例模式对于无会话状态的 Bean(如 DAO 层、Service 层)来说,是最理想的选择。
在 Spring 配置文件中,可以使用 <bean> 元素的 scope 属性,将 Bean 的作用域定义成 singleton,其配置方式如下所示:

<bean id="person" class="com.mengma.scope.Person" scope="singleton"/>

1. 创建项目,完善结构,导入依赖

2. 创建UserBean

package com.wangxing.springdemo4.testscope1;
public class UserBean {
    public  void testUser(){
        System.out.println( "UserBean类的testUser()实例方法" );
    }
}

3. 创建Spring配置文件

<?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">
    <!--singleton是默认的作用域-->
    <bean id="user" class="com.wangxing.springdemo4.testscope1.UserBean" scope="singleton"></bean>
</beans>

4. 测试

@Test
public void test1() {
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    UserBean userBean1= context.getBean("user",UserBean.class);
    UserBean userBean2= context.getBean("user",UserBean.class);
    System.out.println("userBean1--"+userBean1.hashCode());
    System.out.println("userBean2--"+userBean2.hashCode());
}

两次输出的结果相同,这说明 Spring 容器只创建了一个 UserBean类的实例。由于 Spring 容器默认作用域是 singleton,如果不设置 scope="singleton",则其输出结果也将是一个实例。

prototype 作用域

使用 prototype 作用域的 Bean 会在每次请求该 Bean 时都会创建一个新的 Bean 实例。因此对需要保持会话状态的 Bean(如 Struts2 的 Action 类)应该使用 prototype 作用域。
在 Spring 配置文件中,要将 Bean 定义为 prototype 作用域,只需将 <bean> 元素的 scope 属性值定义成 prototype,其示例代码如下所示:

<bean id="person" class="com.mengma.scope.Person" scope="prototype"/>

1. 创建项目,完善结构,导入依赖

2. 创建UserBean

package com.wangxing.springdemo4.testscope2;
public class Student {
    public  void testStudent(){
        System.out.println( "Student类testStudent()实例方法" );
    }
}

3. 创建Spring配置文件

<?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">
    <!--通过scope设置原型模式-->
    <bean id="student" class="com.wangxing.springdemo4.testscope2.Student" scope="prototype"></bean>
</beans>

4. 测试

@Test
public void test1() {
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student1= context.getBean("student",Student.class);
    Student student2= context.getBean("student",Student.class);
    System.out.println("student1--"+student1.hashCode());
    System.out.println("student2--"+student2.hashCode());
}

输出结果中可以看到,两次输出的结果并不相同,这说明在 prototype 作用域下,Spring 容器创建了两个不同的 Student实例。

Spring Bean的生命周期

Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。
而对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。每次客户端请求 prototype 作用域的 Bean 时,Spring 容器都会创建一个新的实例,并且不会管那些被配置成 prototype 作用域的 Bean 的生命周期。
了解 Spring 生命周期的意义就在于,可以利用 Bean 在其存活期间的指定时刻完成一些相关操作。这种时刻可能有很多,但一般情况下,会在 Bean 被初始化后和被销毁前执行一些相关操作。
在 Spring 中,Bean 的生命周期是一个很复杂的执行过程,我们可以利用 Spring 提供的方法定制 Bean 的创建过程。
当一个 Bean 被加载到 Spring 容器时,它就具有了生命,而 Spring 容器在保证一个 Bean 能够使用之前,会进行很多工作。Spring 容器中 Bean 的生命周期流程如图所示。


   Bean 的生命周期

Bean 生命周期的整个执行过程描述如下。

1)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。
2)利用依赖注入完成 Bean 中所有属性值的配置注入。
3)如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
4)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
5)如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
6)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
7)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
8)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
10)如果在 <bean> 中指定了该 Bean 的作用范围为 scope="singleton",则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 <bean> 中指定了该 Bean 的作用范围为 scope="prototype",则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
11)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。
Spring 为 Bean 提供了细致全面的生命周期过程,通过实现特定的接口或 <bean> 的属性设置,都可以对 Bean 的生命周期过程产生影响。虽然可以随意配置 <bean> 的属性,但是建议不要过多地使用 Bean 实现接口,因为这样会导致代码和 Spring 的聚合过于紧密。

1.创建项目,完善结构,导入依赖

2.创建UserBean

package com.wangxing.springdemo5;
public class PersonBean {
    public PersonBean(){
        System.out.println("创建PersonBean对象");
    }
    public void initPerson(){
        System.out.println("initPerson()是我们定制的初始化方法");
    }
    public void testPerson(){
        System.out.println("testPerson()是PersonBean的实例方法");
    }
    public void  destoryPerson(){
        System.out.println("destoryPerson()是我们定制的销毁方法");
    }
}

3.创建Spring配置文件

<?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">
    <bean id="person" class="com.wangxing.springdemo5.PersonBean" scope="singleton" init-method="initPerson" destroy-method="destoryPerson"></bean>
</beans>

4. 测试

@Test
public void test1(){
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    PersonBean personBean=context.getBean("person",PersonBean.class);
    personBean.testPerson();
//关闭Spring容器对象
    //((AbstractApplicationContext)context).close();
    ((AbstractApplicationContext)context).registerShutdownHook();
}

当spring配置文件中的scope属性是singleton时,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。

被定制的销毁方法【destoryPerson()】被执行

当spring配置文件中的scope属性是prototype时,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。

被定制的销毁方法【destoryPerson()】不会执行

Spring给复杂的J2EE开发带来了春天。它的核心是轻量级的IoC容器,它的目标是为J2EE应用提供了全方位的整合框架,在Spring框架下实现多个子框架的组合,这些子框架之间可以彼此独立,也可以使用其它的框架方案加以代替,Spring希望为企业应用提供一站式(one-stopshop)的解决方案。

猜你喜欢

转载自blog.csdn.net/weixin_53123681/article/details/115558866