下面我们讲一个Prototype和Singleton的混合实例。

假设我们有一个PersonDAO

@Component
public class PersonDAO {

	@Autowired
	JdbcConnection jdbcConnection;

	public JdbcConnection getJdbcConnection() {
		return jdbcConnection;
	}

	public void setJdbcConnection(JdbcConnection jdbcConnection) {
		this.jdbcConnection = jdbcConnection;
	}

}

在PersonDAO里我们使用JdbcConnection来获取连接

@Component
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class JdbcConnection {
	public JdbcConnection() {
		System.out.println("JDBC Connection");
	}
}

通过上面的代码我们可以看出

PersonDAO的作用域是singleton

JdbcConnection的作用域是prototype

那么,下面的输出结果什么呢?

  • bean1和bean2会相同吗?
  • bean1.getJdbcConnection()与 bean2.getJdbcConnection()会相同吗?
		ApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
		PersonDAO bean1 = applicationContext.getBean(PersonDAO.class);
		PersonDAO bean2 = applicationContext.getBean(PersonDAO.class);
		System.out.println(bean1);
		System.out.println(bean1.getJdbcConnection());
		System.out.println(bean2);
		System.out.println(bean2.getJdbcConnection());

bean1.getJdbcConnection()与 bean2.getJdbcConnection()竟然也是相同的 。

因为当你把声明为相对范围小的作用域(例如:prototy)对象注入到相对范围大的作用域(例如:singleton)对象时,由于外层对象只会初始化一次,所以会导致内部注入的对象也只会被初始化一次。

那我们怎么 解决呢 ? 我们可以使用proxyMode来解决。

@Component
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE
	, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class JdbcConnection {
	public JdbcConnection() {
		System.out.println("JDBC Connection");
	}
}