Learning the scope of Spring's Bean

This article has participated in the "Newcomer Creation Ceremony" event to start the road of gold creation together.

1. bean management

1. Ordinary beans

Defining the bean type in the configuration file is the return type

2. The project bean is the FactoryBean

Defining the bean type in the configuration file can be different from the return type

  • Create a class, make this class a factory bean, and implement the interface FactoryBean
  • Implement the methods in the interface, and define the returned bean type in the implemented method

Create a different return value

public class MyBean implements FactoryBean<Course> {

//定义返回Bean
    @Override
    public Course getObject() throws Exception {
        Course course = new Course();
        course.setCname("张思思");
        return course;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}
复制代码
<?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="myBean" class="com.Spring.Collection.MyBean">

</bean>
</beans>
复制代码
public class Course {
    private String cname;//课程名称

    public void setCname(String cname) {
        this.cname = cname;
    }

    @Override
    public String toString() {
        return "Course{" +
                "cname='" + cname + '\'' +
                '}';
    }
}
复制代码

Ultimately an object of a class that implements Course

 @Test
    public void myBean() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        Course mybean = context.getBean("myBean", Course.class);
        System.out.println(mybean);
    }
复制代码

2. Bean scope

In Spring, the objects that make up the body of an application and are managed by the Spring IoC container are called beans. Simply put, a bean is an object initialized, assembled and managed by an IoC container

图片.png

Among the several scopes, the request and session scopes are only used in web-based applications (don't care what web application framework you use), and can only be used in the web-based Spring ApplicationContext environment.

Singleton When the scope of a bean is Singleton, then there is only one shared bean instance in the Spring IoC container, and all requests to the bean, as long as the id matches the bean definition, will only return the same instance of the bean. Singleton is a singleton type, that is, when the container is created, a bean object is automatically created at the same time, whether you use it or not, it exists, and the object obtained each time is the same object. Note that Singleton scope is the default scope in Spring. To define a bean as a singleton in XML, you can configure it like this: 1 <bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">Test

@Test
public void test03(){
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
System.out.println(user==user2);
}
复制代码

Prototype 当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会 导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法) 时都会创建一个新的bean实例。Prototype是原型类型,它在我们创建容器的时候并没有实例化,而是 当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经 验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。在 XML中将bean定义成prototype,可以这样配置:

<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>
或者
<bean id="account" class="com.foo.DefaultAccount" singleton="false"/>
复制代码

Request 当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例;即每个HTTP 请求都会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:

<bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>

复制代码

针对每次HTTP请求,Spring容器会根据loginAction bean的定义创建一个全新的LoginAction bean实 例,且该loginAction bean实例仅在当前HTTP request内有效,因此可以根据需要放心的更改所建实例 的内部状态,而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的 状态变化。当处理请求结束,request作用域的bean实例将被销毁。 Session 当一个bean的作用域为Session,表示在一个HTTP Session中,一个bean定义对应一个实例。该作用域 仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
复制代码

针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的 userPreferences bean实例,且该userPreferences bean仅在当前HTTP Session内有效。与request作 用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据 userPreferences创建的实例,将不会看到这些特定于某个HTTP Session的状态变化。当HTTP Session 最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。

1.设置创建Bean实例是单实例还是多实例

在Spring下默认是单实例对象

1.在Spring配置文件bean标签里面有属性用于设置单实例还是多实例       scope="" 就是设置多实例还是单实例

  • prototype是多实例
  • singleton是单实例也是默认实例
<?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="book" class="com.Spring.IOC.Book" scope="prototype">
    <property name="bname" value="java开发"></property>
</bean>
</beans>
复制代码
public class Book {
    private String  bname;
    public void setBname(String bname) {
        this.bname = bname;
    }
}

复制代码

图片.png

prototype与singleton的区别

  • 设置scope是singleton的时候,加载Spring配置文件就会创建单实例对象
  • scope是prototype的时候,不是在加载Spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象

6.Bean的生命周期

1.过程

  • 通过构造器创建Bean实例(无参构造)
  • 为Bean的属性设置值和对其他Bean引用(调用set方法)
  • 调用Bean的初始化方法(需要进行配置初始化方法)
  • Bean可以使用了(对象获取到了)
  • 当容器关闭时,调用Bean的销毁的方法(需要进行配置销毁方法)
public class Orders {
    private String oname;

    public Orders() {
        System.out.println("1.执行无参数构造创建Bean实例");
    }

    public void setOname(String oname) {
        this.oname = oname;
        System.out.println("2.调用set方法设置属性值");
    }
    public void initMethod(){
        System.out.println("3.执行初始化的方法");
    }
    public void destroyMethod(){
        System.out.println("5.执行销毁方法");
    }
}
复制代码

测试类

 @Test
    public void testBean() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        Orders orders = context.getBean("orders2",Orders.class);
        System.out.println("4.获取创建Bean实例对象");
        System.out.println(orders);
        //手动销毁Bean实例
        ((ClassPathXmlApplicationContext) context).close();
    }
复制代码

xml配置里面要加上init-method 和destory-method这两个方法都在Orders类里面创建

<bean id="orders2" class="com.Spring.Collection.Orders" init-method="initMethod" destroy-method="destroyMethod">
        <property name="oname" value="手机"></property>
    </bean>
复制代码

2.添加后置处理器后有七步

  • 通过构造器创建Bean实例(无参构造)
  • 为Bean的属性设置值和对其他Bean引用(调用set方法)
  • 把Bean实例传给Bean后置处理器的方法
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
复制代码
  • 调用Bean的初始化方法(需要进行配置初始化方法)
  • 把Bean实例传递给Bean后置处理器的方法
 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
复制代码
  • Bean可以使用了(对象获取到了)
  • 当容器关闭时,调用Bean的销毁的方法(需要进行配置销毁方法)

添加后置处理器方法实现BeanPostProcessor,创建后置处理器

public class MyBeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前执行的方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化方法之后执行的方法");
        return bean;
    }
}
复制代码
public class Orders {
    private String oname;

    public Orders() {
        System.out.println("1.执行无参数构造创建Bean实例");
    }

    public void setOname(String oname) {
        this.oname = oname;
        System.out.println("2.调用set方法设置属性值");
    }
    public void initMethod(){
        System.out.println("3.执行初始化的方法");
    }
    public void destroyMethod(){
        System.out.println("5.执行销毁方法");
    }
}
复制代码

只需要将配置的后置对象加入到配置的文件中,在里面的其他配置实例都会有后置对象

<?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="orders2" class="com.Spring.Collection.Orders" init-method="initMethod" destroy-method="destroyMethod">
        <property name="oname" value="手机"></property>
    </bean>
    <!--配置后置处理器-->
    <bean id="myBeanPost" class="com.Spring.Collection.MyBeanPost">
<--7-->
    </bean>
</beans>
复制代码

图片.png

Guess you like

Origin juejin.im/post/7084582900468809735