我正在学习 Spring Core 认证,我发现一些与代理概念相关的疑问。
因此,在学习材料中,我找到了以下测验:
有一个 Java配置类,其中包含以下方法:
@Bean
public AccountRepository accountRepository(){
return new JdbcAccountRepository();
}
@Bean
public TransferService transferService1() {
TransferServiceImpl service = new TransferServiceImpl();
service.setAccountRepository(accountRepository());
return service;
}
@Bean
public TransferService transferService2() {
return new TransferServiceImpl( new JdbcAccountRepository() );
}
如您所见, transferService() 有 2 个不同的实现,分别命名为transferService1()和transferService2(),它们创建并返回一个TransferServiceImpl对象。
第一个创建一个新的TransferServiceImpl对象,然后对其调用setAccountRepository()方法。
第二个简单地创建一个TransferServiceImpl,将一个新的JdbcAccountRepository对象传递给它的构造函数。
它问我**在前两种方法中哪个是最好的实现?
提供的答案是:Prefer call to dedicated method。所以我认为它说最好的方法是第一次实施。
它解释了AccountRepository bean 是一个单例(因为它是 Spring 中 bean 的标准范围)但是JdbcAccountRepository()可以被调用两次或更多次(例如在前面的代码片段中,它在调用方法时被调用transferService1()和transferService2()如果是这样,这将是一个问题,因为AccountRepository必须是一个单例。
这是真的吗?还是我错过了什么?
所以我收集到在启动时 foreach 配置类(用@Configuration注释)创建了一个扩展我的配置类的子类。
例如,如果我有以下配置类:
@Configuration
public class AppConfig {
@Bean public AccountRepository accountRepository() { ... }
@Bean public TransferService transferService() { ... }
}
它会自动创建以下扩展我的AppConfig的类:
public class AppConfig$$EnhancerByCGLIB$ extends AppConfig {
public AccountRepository accountRepository() { // ... }
public TransferService transferService() { // ... }
...
...
...
}
所以子类是入口点(调用的方法是在子类中定义的方法),伪代码将是这样的:
public class AppConfig$$EnhancerByCGLIB$ extends AppConfig {
public AccountRepository accountRepository() {
// if bean is in the applicationContext return bean
// else call super.accountRepository() and store bean in context
}
public TransferService transferService() {
// if bean is in the applicationContext, return bean
// else call super.transferService() and store bean in context
}
}
所以很清楚 Spring 如何处理单例问题:它调用扩展配置类的代理类上的方法,如果请求的 bean 存在于 applicationContext 中,则返回此 bean,否则在创建的超类上调用相同的方法新 bean 并将其放入应用程序上下文中
这是基于代理模式的继承的正确含义还是我遗漏了什么?