spring 中的 bean 是线程安全的吗?
Spring 不保证 bean 的线程安全。
默认 spring 容器中的 bean 是单例的。ZFX代理申请www.fx61.com/brokerlist/zfx.html,当单例中存在竞态条件,即有线程安全问题。如下面的例子
计数类
package constxiong.interview.threadsafe;
/**
- 计数类
- @author ConstXiong
- @date 2019-07-16 14:35:40
*/
public class Counter {
private int count = 0;
public void addAndPrint() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(++count);
}
}
spring 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<bean id="counter" class="constxiong.interview.threadsafe.Counter" />
</beans>
测试类
package constxiong.interview.threadsafe;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CounterTest {
public static void main(String[] args) {
final ApplicationContext context = new ClassPathXmlApplicationContext("spring_safe.xml");
for (int i = 0; i < 10; i++) {
new Thread(){@Override
br/>@Override
Counter counter = (Counter)context.getBean("counter");
for (int j = 0; j < 1000; j++) {
counter.addAndPrint();
}
}
}.start();
}
}
}
打印结果开头和结尾
9818
9819
9820
9821
9822
9823
9824
9825
期望打印出的最大值应该是 10000
修改 spring 配置文件,把 bean 的作用域改为 prototype
<?xml version="1.0" encoding="UTF-8"?>
<bean id="counter" class="constxiong.interview.threadsafe.Counter" scope="prototype"
</beans>
测试结果输出10
spring 是一个开源的轻量级 JavaBean 容器框架。使用 JavaBean 代替 EJB ,并提供了丰富的企业应用功能,降低应用开发的复杂性。
轻量:非***性的、所依赖的东西少、资源占用少、部署简单,不同功能选择不同的 jar 组合
容器:工厂模式实现对 JavaBean 进行管理,通过控制反转(IOC)将应用程序的配置和依赖性与应用代码分开
松耦合:通过 xml 配置或注解即可完成 bean 的依赖注入
AOP:通过 xml 配置 或注解即可加入面向切面编程的能力,完成切面功能,如:日志,事务...的统一处理
方便集成:通过配置和简单的对象注入即可集成其他框架,如 Mybatis、Hibernate、Shiro...
丰富的功能:JDBC 层抽象、事务管理、MVC、Java Mail、任务调度、JMX、JMS、JNDI、EJB、动态语言、远程访问、Web Service...