下
期进
入
springboot
咯
~
目录
1.Bean的作用域
①什么是Bean的作用域:
实质上是指Bean在spring整个框架中的某种行为模式,比如singleton单例模式,就是指Bean在整个作用域中只有一份,并且是全局共享的,当其他人在任意处修改了,那么其他人读到的就是修改后的数据。
②对①中进行示例:
(大概思路就是通过公共Bean部分来对原值进行设置,然后我们用A用户对其实行修改,并接着用B用户去进行获取,看得到的值是否一致)
(1)公共Bean的部分(我们将公共bean设置于此)
package inBean; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @Component public class Users { @Bean public User user1(){ User user=new User(); user.setName("张三"); user.setId(1); return user; } }
(2)A用户对原来数据进行修改:
package inBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import javax.annotation.Resource; @Controller public class UserController4 { @Autowired private User user1; public User getUser(){ User user=user1; System.out.println("修改前的名称+ID"+user.getName()+user.getId()); user.setId(2); user.setName("李四"); return user; } }
(3)B用户对修改后的数据来进行获取:
package inBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class UserController3 { @Autowired private User user1; public User getUser1(){ User user=user1; return user; } }
(4)main:
import inBean.*; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { //1.先获取对象的上下文 ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); //方式一 UserController4 userController4=context.getBean("userController4",UserController4.class); System.out.println("A修改后的对象"+userController4.getUser().toString()); UserController3 userController3=context.getBean("userController3",UserController3.class); System.out.println(userController3.getUser1()); } }
输出结果:
![]()
我们在这里看到修改前的名字+ID分别为张三 1,但是当A用户进行修改后,B用户去获取到的值也是修改后的值。这是为什么呢?
这是因为spring中bean的默认情况下是单例模式,也就是修改后所有其他的读取到的都是修改后的值。
1.1Bean的六大作用域
①singleton:单例作用域(默认)
通常无状态(bean的状态不需要修改)下的bean就会使用该作用域,而且每一次注入的bean都是同一个bean。并且这是一种默认状态
②prototype:原型作用域(多例作用域)
原例模式实质上就是类似于多例模式,每次对该作用域下的Bean时,就会创建出新的实例。
③request:请求作用域(Spring MVC)
每次HTTP请求时就会创建出新的实例,一次HTTP请求和响应共用Bean,限于在spring MVC中使用。
④session:会话作用域(Spring MVC)
在用户会话的时候共享bean,举个例子,在你登录某个APP时,你的登录信息会被存储起来,这个时候就相当于在你登录期间,一直是在共享bean。
⑤application:全局作用域(Spring MVC)
这是关于web的上下文信息,只需了解即可。
⑥websocket: HTTP WebSocket 作用域(Spring WebSocket)
只需了解即可。
1.2设置Bean的作用域
①直接设置:
(1)方法:
使用@Scope(“prototype”),直接将其加在Bean下即可。
(2)演示:前面我们演示了默认情况下是单例模式,此时,我们就在该单例模式的基础上来实现这个@Scope(“prototype”),使其可以成为多例模式,即修改后并不影响原来的值。
![]()
②使用枚举设置:
(这里的枚举设置并不是说真的就是枚举,只是类似于这种形式罢了)
(1)方法:(这个的优势在于不容易输错)
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
(2)演示:(仍然是以上面这个例子来进行修改)
![]()
实现的是和①中同样的效果,只是方法里面参数不同罢了。
2.Bean的执行流程
①简单叙述:
当我们启动容器的时候,执行main函数时,首先会对Application中的类加载路径进行加载(spring-config.xml),紧接着会根据该xml文件中的配置扫描找到对应的包,找到对应的包后,就会开始扫描里面的spring注解,然后将Bean对象注册到容器中,这个时候如果bean对象有其他属性,也会进行读取。
②图例展示:
![]()
3.Bean的生命周期
Bean的生命周期主要分为5大过程,这里我们简单地对这五大过程进行讲解。
①实例化Bean:(买房)
实质上就是为bean分配内存空间
②设置属性:(装修)
就是指的是bean注入和配置
③Bean的初始化:(购置家具)
a.执行各种通知(执行各种 Aware)
b. 执行初始化的前置方法;
c. 执行构造方法,两种执行方式,一种是执行@PostConstruct,另一种实质性 init-method;
d. 执行初始化的后置方法;
④使用Bean(入住)
⑤销毁bean:(卖房)
a.@PreDestory
b. 重写DisposableBean接口方法
c.destroy-method下面我们来用代码证实一下确实经过了这些过程:
import org.springframework.beans.factory.BeanNameAware; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @Component public class BeanLifeComponent implements BeanNameAware { @PostConstruct public void postConstruct() { System.out.println("执行 @PostConstruct"); } public void init() { System.out.println("执行 init-method"); } public void use() { System.out.println("使用 bean"); } @PreDestroy public void preDestroy() { System.out.println("执行了 @PreDestroy"); } public void setBeanName(String s) { System.out.println("执行了 Aware 通知"); } } import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); BeanLifeComponent beanLifeComponent = context.getBean("beanLifeComponent",BeanLifeComponent.class); beanLifeComponent.use(); context.destroy(); } }
输出结果:
![]()
下期我们将讲解springboot相关内容~