gpt4 book ai didi

Spring Java 配置 - @DependsOn 链接

转载 作者:行者123 更新时间:2023-12-02 09:56:55 25 4
gpt4 key购买 nike

我有一个 3.2.14.RELEASE spring 应用程序,并且正在使用 java 配置来连接和注入(inject) bean。

就我而言,我需要

  1. 设置 SSH 隧道
  2. 创建一个数据源,以便它使用相同的 ssh隧道 session
  3. 创建一个 Query 类,使用以下命令执行 SQL 查询一个 JDBC 模板

我已经设置了我的 ApplicationContext 链接,并使用 @DependsOn 注释来链接这三个 bean

package com.b.e.kpireport;

@Configuration
@ComponentScan(basePackages = {"com.b.e.kpireport" })
public class ApplicationContext {

@Bean(name = "sshTunnel")
public SSHTunnel getSSHTunnel() {
return new SSHTunnel();
}

@Bean(name = "dataSource" )
@DependsOn("sshTunnel")
public DataSource getDataSource() {

DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(jdbcUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
logger.info("getDataSource():"+jdbcUrl+":"+username+"/"+password+":"+driver);
return dataSource;
}

@Bean
@DependsOn("dataSource")
public Query getQuery() {
return new Query();
}
}

查询类看起来像

class Query {

private JdbcTemplate jdbcTemplate;

@Autowired
private DataSource dataSource;

@Autowired
private SSHTunnel sshTunnel;

public void runQuery() {
sshTunnel.openSession();
jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute(sql);
}

无论我尝试过什么,我都发现数据源是在 SSHTunnel 之前初始化的

Aug 26, 2015 5:20:44 PM com.b.e.kpireport.ApplicationContext getDataSource
INFO: getDataSource():jdbc:mysql://localhost:3006/centstorage:davidobrien/MnBufeuwncv3eR:com.mysql.jdbc.Driver
Aug 26, 2015 5:20:44 PM com.b.e.kpireport.SSHTunnel openSession
INFO: openSession

关于如何确保正确的 bean 初始化顺序有什么建议吗?

最佳答案

解决方案实际上可能很简单:

@Configuration
public class ApplicationContext {
@Bean(name = "sshTunnel")
public SSHTunnel getSSHTunnel() {
return new SSHTunnel();
}

@Bean(name = "dataSource" )
public DataSource getDataSource() {
getSHTunnel();
DriverManagerDataSource dataSource = new DriverManagerDataSource();
// ...
return dataSource;
}

@Bean
public Query getQuery() {
return new Query(getSSHTunnel(), getDataSource());
}
}

我们经常使用这种调用配置类方法(从类内部)的模式。创建上下文时,不会直接在您的类上调用这些方法,而是在 Spring 动态创建的子类上调用这些方法。这确保了即使您多次调用一个方法(例如 getSSHTunnel() ),相应的 bean 也只会创建一次(即只会创建一个隧道)。

我也更喜欢通过构造函数传递依赖项,而不是使用 @Autowired - 它不那么神奇并且更容易测试。但这是可选的。

我不知道为什么使用 @DependsOn不过,这对你不起作用。当我在本地尝试时,它有效(使用相同的 Spring 版本)。无论如何,上面是一个如何完全不使用它的示例。

<小时/>

编辑以回复评论:

But in this case you can just delete all the spring annotations since you are not doing any dependency injection. You've basically just got a plain old java object

事实并非如此。正如我所说,在 @Configuration 对象上调用方法不会直接调用您的方法,而是它的版本被 Spring returning the bean according to configuration 覆盖。 。这允许您进行正确的依赖项注入(inject),例如在这样的测试中:

@Configuration 
public class TestDependencies {
@Bean(name="dataSource")
public DataSource getDataSource() {
return new MockDataSource();
}
}
...
ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationContext.class, TestDependencies.class);
context.getBean("dataSource"); // returns MockDataSource

换句话说,调用像 getDataSource() 这样的方法实际上相当于具有依赖关系 @Autowired或使用context.getBean() 。 AFAIK 这种方法没有任何陷阱(只要你不向 @Bean 方法传递参数,否则事情会变得有点奇怪),而且我们已经使用它很长时间了。

关于Spring Java 配置 - @DependsOn 链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32231972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com