我有两颗豆子 PersonDAO
以及 JdbcConnection
彼此依赖。这个 PersonDAO
bean是使用 @Component
. 但是 JdbcConnection
是一个 prototype
因为它被注射在 PersonDAO
我正在使用 proxyMode = ScopedProxyMode.TARGET_CLASS
以确保它是一个不同的示例(不是单例)。
import com.github.felipegutierrez.explore.spring.basics.beans.JdbcConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class PersonDAO {
@Autowired
private JdbcConnection jdbcConnection;
public PersonDAO(JdbcConnection jdbcConnection) {
this.jdbcConnection = jdbcConnection;
}
public JdbcConnection getJdbcConnection() {
return jdbcConnection;
}
public void setJdbcConnection(JdbcConnection jdbcConnection) {
this.jdbcConnection = jdbcConnection;
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class JdbcConnection {
private static final Logger LOGGER = LoggerFactory.getLogger(JdbcConnection.class);
public JdbcConnection() {
// LOGGER.info("This is my JdbcConnection that is not a singleton bean.");
}
}
当我打印它们的对象示例时 PersonDAO
是独生子女 JdbcConnection
是另一个例子。但是 JdbcConnection
说是独生子。为什么?
ApplicationContext applicationContext = SpringApplication.run(ExploreSpringApplication.class, args);
PersonDAO personDAO01 = applicationContext.getBean(PersonDAO.class);
PersonDAO personDAO02 = applicationContext.getBean(PersonDAO.class);
LOGGER.info("DAO 01: {}, {}, JDBCConnection: {}, {}", personDAO01, personDAO01.hashCode(), personDAO01.getJdbcConnection().hashCode(), personDAO01.getJdbcConnection());
LOGGER.info("DAO 02: {}, {}, JDBCConnection: {}, {}", personDAO02, personDAO02.hashCode(), personDAO02.getJdbcConnection().hashCode(), personDAO02.getJdbcConnection());
输出 JDBCConnection
的 DAO01
以及 DAO02
具有相同的哈希代码: 1596179075
但实际上它们是不同的例子: JdbcConnection@58a55449
以及 JdbcConnection@5949eba8
:
2021-03-08 18:13:29.527 INFO 10329 --- [ main] c.g.f.e.spring.ExploreSpringApplication : DAO 01: 1187972599, com.github.felipegutierrez.explore.spring.basics.dao.PersonDAO@46cf05f7
2021-03-08 18:13:29.527 INFO 10329 --- [ main] c.g.f.e.spring.ExploreSpringApplication : DAO 01 JDBCConnection: 1596179075, com.github.felipegutierrez.explore.spring.basics.beans.JdbcConnection@58a55449
2021-03-08 18:13:29.529 INFO 10329 --- [ main] c.g.f.e.spring.ExploreSpringApplication : DAO 02: 1187972599, com.github.felipegutierrez.explore.spring.basics.dao.PersonDAO@46cf05f7
2021-03-08 18:13:29.529 INFO 10329 --- [ main] c.g.f.e.spring.ExploreSpringApplication : DAO 02 JDBCConnection: 1596179075, com.github.felipegutierrez.explore.spring.basics.beans.JdbcConnection@5949eba8
1条答案
按热度按时间qhhrdooz1#
spring在为目标原型对象创建代理时默认使用cglib。似乎这是cglib的一个限制
hashCode()
以及equals
方法总是被特殊的拦截器截获,这些拦截器以不经过目标对象的方式进行比较。如果您切换到基于jdk接口的代理,这需要
JdbcConnection
实现一个接口,您可以声明hashCode()
以及equals()
在界面中:Spring的
JdkDynamicAopProxy
然后打电话给hashCode()
以及equals()
在目标对象上。使用
@Qualifier("jdbcConnection")
界面在PersonDAO
.