
Bean的作用域其实就是bean在spring整个框架中的某种行为,而一般bean在spring中默认是单例模式,下面一起来看看bean的所有作用域吧!
通常无状态(bean的状态不需要修改)下的bean就会使用该作用域,而且每一次注入的bean都是同一个bean;
原型模式其实就是相对于单例模式的多例模式,通常有状态的情况下使用该作用域,每一次注入的时候都会创建一个新的bean对象;
这个是Spring MVC项目中独有的作用域,每一次http请求都会创建bean实例,类似于原型模式不过两种作用域发生在不同的项目里面;
这个也是Spring MVC项目中的,在一个http session中都会共享一个bean实例,来记录一个用户的登录信息;
这个也是Spring MVC项目中的,通常在一个http servlet Context中定义一个bean实例在Web应用的上下文中都是使用一个bean,这个作用域了解即可;
这个是Spring WebSocket项目里面的作用域,在一个http WebSocket的生命周期中,会定义一个bean,这个作用域了解即可;
区别:
@Component
public class UserBeans {
@Bean(name = {"userinfo"})
public User getUser(){
User user = new User();
user.setId(1);
user.setName("小狗");
return user;
}
}
@Component
public class BeanScope1 {
@Autowired
private User userinfo;
public User getUser(){
User user = userinfo;
user.setName("张三");
return user;
}
}
@Component
public class BeanScope2 {
@Autowired
private User userinfo;
public User getUser(){
return userinfo;
}
}
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
BeanScope1 beanScope1 = context.getBean(BeanScope1.class);
User user1 = beanScope1.getUser();
System.out.println("BeanScope1:" + user1);
BeanScope2 beanScope2 = context.getBean(BeanScope2.class);
User user2 = beanScope2.getUser();
System.out.println("BeanScope2:" + user2);
}
}

通过这个案例,就体现出了bean的单例模式,两次获得到的都是同一个bean,当第一个发生了改变,第二个也随之发生改变;
而想要修改作用域,就需要使用@Scope注解来进行设置,@Scope既可以修饰方法也可以修饰类,这里有两种设置修改bean的作用域的方式:
@Scope(“prototype”)直接加在@Bean标签的下面就可以了
@Component
public class UserBeans {
@Bean(name = {"userinfo"})
@Scope("prototype")
public User getUser(){
User user = new User();
user.setId(1);
user.setName("小狗");
return user;
}
}
这样就作用域就变成了原型模式就是每次读取bean都会获得到一个新的bean对象

就会发现原本的小狗并没有发生改变!
这样的设置方式是类似于枚举常量一样的形式,@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)也是和上面一样的写法
@Component
public class UserBeans {
@Bean(name = {"userinfo"})
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public User getUser(){
User user = new User();
user.setId(1);
user.setName("小狗");
return user;
}
}

两种方法效果都是一样的,都可以将单例模式改成原型模式!

先来看一下Bean的执行流程(Spring的执行流程):
启动Spring容器->根据xml配置完成Bean的初始化->通过五大类注解存储Bean到Spring容器中->将Bean注入到需要的类中;
了解了这个再来看一下Bean的生命周期:
Bean的生命周期其实就是Bean对象从诞生到销毁的整个过程,就成为生命周期,而Bean的生命周期可以分为5个部分,可以一起来看一下:
实例化不是初始化,就是为bean分配内存空间;
设置属性就是对象注入;
执行Aware通知;
执行构造方式有两种方式:
这两种都是进行初始化,只不过是不同时代的产物罢了,而注解的优先级会高于init-method方法,不过一般不会两种都使用;
销毁bean的方法:@PreDestroy和destroy-method方法,这也和上面的初始化方式是同样的道理,只是不同时代的产物,另外如果有实现接口,需要重写DisposableBean接口方法。
