请查看以下代码:
@Component
@Scope(value= ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class JdbcConnection {
public JdbcConnection() {
System.out.println("JDBC Connection");
}
}
@Component
public class PersonDAO {
@Autowired
JdbcConnection jdbcConnection;
public JdbcConnection getJdbcConnection() {
return jdbcConnection;
}
public void setJdbcConnection(JdbcConnection jdbcConnection) {
this.jdbcConnection = jdbcConnection;
}
}
@SpringBootApplication
public class SpringIn5StepsApplication {
private static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(SpringIn5StepsApplication.class);
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(SpringIn5StepsApplication.class, args);
PersonDAO personDao = applicationContext.getBean(PersonDAO.class);
PersonDAO personDao2 = applicationContext.getBean(PersonDAO.class);
LOGGER.info("{}", personDao);
LOGGER.info("{}", personDao.getJdbcConnection());
LOGGER.info("{}", personDao2);
LOGGER.info("{}", personDao2.getJdbcConnection());
}
}
运行我们在控制台中获取的代码时:
:com.spring.basics.springin5steps.scope.PersonDAO@352c1b98: com.spring.basics.springin5steps.scope.JdbcConnection@41005828: com.spring.basics.springin5steps.scope.PersonDAO@352c1b98: com.spring.basics.springin5steps.scope.JdbcConnection@60b4beb4
这意味着personDao和personDao2基本上是同一个对象。如果是这样,从对象personDao获取属性jdbcConnection后,我们得到两个不同的对象怎么可能?
答案 0 :(得分:1)
您使用的是ScopedProxyMode.TARGET_CLASS
和ConfigurableBeanFactory.SCOPE_PROTOTYPE
。
因此,spring会生成基于cglib的代理并将其注入您的PersonDAO
类。
每个方法调用的代理使用新的JdbcConnection
(因为范围是prototype
)并委托方法调用它。
当您打印JdbcConnection
时,隐式调用导致toString()
创建new JdbcConnection()
的{{1}},将调用toString()
方法。
如果是这样,从对象personDao获取属性jdbcConnection后,我们得到两个不同的对象怎么可能?
不,你有相同的对象,但是在不同的对象上调用了toString()
方法。试试这个:
JdbcConnection connection1 = dao.getJdbcConnection();
JdbcConnection connection2 = dao.getJdbcConnection();
System.out.println("connection1 == connection2: " + (connection1 == connection2));
输出:
connection1 == connection2:true