1:Spring创建的对象,对象的作用域有哪些?
Spring的Bean有以下五种作用域
singleton:SpringIOC容器只会创建该Bean的唯一实例;
prototype:每次请求都创建一个实例;
request:每次HTTP请求都会产生一个新的bean。需要注意的是,该作用域仅在基于Web的Spring ApplicationContext情形下有效,以下的session和global Session也是如此;
Session:每次会话创建一个实例;
global session:全局HttpSession中,容器会返回该bean的同一个实例。
2:Spring bean对象的生命周期
单例对象生命周期和容器的生命周期一致
多例对象在容器创建的时候并不会创建,在使用时创建,属于懒加载,在容器销毁时不会销毁,有jvm的垃圾回收机制自动销毁
3:如何避免spring 单例对象的线程问题?
3.1:那么出现这种问题如何解决呢?
第一种方式:既然是全局变量惹的祸,那就将全局变量都编程局部变量,通过方法参数来传递。
第二种方式: jdk提供了java.lang.ThreadLocal,它为多线程并发提供了新思路。 (当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本)
那么在什么地方使用ThreadLocal呢?什么变量是请求公用的就将该变量托付给ThreadLocal来管理其线程副本,所以我们在xxxService中使用它。
XXXService.java代码:
private ThreadLocal contentTL = new ThreadLocal();
//private String content;使用contentTL代替content;
……
public boolean saveXXX(String content, ……){
this.contentTL.set(content);
//业务逻辑处理
//在各方法中使用content时候用this.contentTL.get()代替
1
2
}
此类并发篡改数据的问题,可以在开发工具中设置断点调试的方式来模拟并发。即第一次请求运行到断点时,查看content内容,并且不让程序继续往下运行,同时再发起一个请求,查看content内容。如内容是第一次请求的内容,并且让第一个请求跑完后,第二个请求到断线处的content正确时,可以确定不会出现并发问题。
也就是说,如果一个类设计成单例模式, 那么就要注意他的全局变量,如果变量这里没有问题的话方法的调用也不会存在安全问题,因为线程会同时调用同一个对象的方法,但是在内存中有自己独立的空间作为存储,Spring设计成单例Bean主要是为了节省没必要的资源浪费。
4:Aop的应用场景
AOP 可以做权限/事务/日志