Java Spring : proxyMode = ScopedProxyMode. TARGET_CLASS 同一个对象怎么可能有不同的属性?

标签 java spring

请看下面的代码:

@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 后,我们怎么可能得到两个不同的对象呢?

最佳答案

您正在使用ScopedProxyMode.TARGET_CLASSConfigurableBeanFactory.SCOPE_PROTOTYPE

因此 spring 生成基于 cglib 的代理并将其注入(inject)到您的 PersonDAO 类中。 每个方法调用上的代理都使用新的 JdbcConnection (因为范围是 prototype)并将方法调用委托(delegate)给它。

当您打印JdbcConnection时,您隐式调用toString(),这会导致new JdbcConnection()创建toString() 方法将被调用。

If so, how is it possible that after getting the attribute jdbcConnection from the object personDao we get two different objects?

不,您获得了相同的对象,但在不同的对象上调用了 toString() 方法。试试这个:

JdbcConnection connection1 = dao.getJdbcConnection();
JdbcConnection connection2 = dao.getJdbcConnection();
System.out.println("connection1 == connection2: " + (connection1 == connection2));

输出:

connection1 == connection2: true

关于Java Spring : proxyMode = ScopedProxyMode. TARGET_CLASS 同一个对象怎么可能有不同的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46623968/

相关文章:

java - 用 @Cacheable 注释的方法不会被拦截

java - 如何在加载 spring 上下文之前在应用程序启动时创建 bean?

java - 如何将 id 传递给 :value and get data of type List<Ingredient>?

Java - 文本框文本不可见

java - 如何在 Vaadin 8 中输入时间戳

java - 如何通过查询方法(SQLiteDatabase.query)使用此查询?

java - 我可以在同一个服务中使用两个存储库吗?

java - Spring @RequestMapping Controller 转发

java - 如何在 HTML 页面中实现控制台?

java - 为什么 Random.nextInt() %16 有偏差,而 Random.nextInt(16) 却工作得很好?