最近在项目开发过程中关注到一个依赖注入的写法差异,因为本人代码上有点强迫症,看到这种不同人不一样的写法,特意了解了一下,但是依然有部分疑惑未解。
两种写法:(就是传说中最常见的属性注入和构造函数注入)
@Service
public class ContactCodeInfoService {
@Autowired
private ContactCodeInfoMapper contactCodeInfoMapper;
@Autowired
private CorpStaffMapper corpStaffMapper;
、、、、、
}
@Service
public class CrAppService {
private final CrAppRepository crAppRepository;
public CrAppService(CrAppRepository crAppRepository) {
this.crAppRepository = crAppRepository;
}
、、、、、
}
Spring官方推荐的是构造函数,并不推荐属性注入的方式
不推荐使用属性注入的理由的却很充分。 但是当采用构造函数注入会遇到代码很不简洁的问题,一旦需要注入的属性达到了四五个,整个构造函数就会显得很臃肿。
@Service
public class SiteCheckServiceImpl implements SiteCheckService {
private final SitePageSpiderService sitePageSpiderService;
private final SitePageAnalyzeService sitePageAnalyzeService;
private final CheckService checkService;
private final LogEventPublisher processLogEventPublisher;
public SiteCheckServiceImpl(SitePageSpiderService sitePageSpiderService,
SitePageAnalyzeService sitePageAnalyzeService,
CheckService checkService,
LogEventPublisher processLogEventPublisher) {
this.sitePageSpiderService = sitePageSpiderService;
this.sitePageAnalyzeService = sitePageAnalyzeService;
this.checkService = checkService;
this.processLogEventPublisher = processLogEventPublisher;
}
、、、、、、
}
遇到这个问题又继续查略一些资料,结果表示可以通过lombok的@AllArgsConstructor来简化代码,让代码看起来比较整洁
@Service
@AllArgsConstructor
public class SiteCheckServiceImpl implements SiteCheckService {
private final SitePageSpiderService sitePageSpiderService;
private final SitePageAnalyzeService sitePageAnalyzeService;
private final CheckService checkService;
private final LogEventPublisher processLogEventPublisher;
、、、、、
}
这样看起来也确实简洁了很多,但是当遇到有继承的情况下,就显得有些顾此失彼了
public abstract class BaseCheckProviderFactory {
private final ProviderLimitStatus<String> providerLimitStatus;
private final ProviderStrategy<ProviderBean> providerStrategy;
private final Map<String, RateLimiter> providerRateLimiterMap;
private final AppConfigService appConfigService;
public BaseCheckProviderFactory(ProviderLimitStatus<String> providerLimitStatus,
ProviderStrategy<ProviderBean> providerStrategy,
Map<String, RateLimiter> providerRateLimiterMap,
AppConfigService appConfigService) {
this.providerLimitStatus = providerLimitStatus;
this.providerStrategy = providerStrategy;
this.providerRateLimiterMap = providerRateLimiterMap;
this.appConfigService = appConfigService;
}
、、、、、、
}
@Component
public class TextCheckProviderFactory extends BaseCheckProviderFactory<TextCheckRequest, TextCheckResponse> {
private final CheckLibraryService<TextCheckRequest, TextCheckResponse> textCheckLibraryService;
public TextCheckProviderFactory(ProviderLimitStatus<String> providerLimitStatus,
ProviderStrategy<ProviderBean> providerStrategy,
Map<String, RateLimiter> providerRateLimiterMap,
AppConfigService appConfigService,
CheckLibraryService<TextCheckRequest, TextCheckResponse> textCheckLibraryService) {
super(providerLimitStatus, providerStrategy, providerRateLimiterMap, appConfigService);
this.textCheckLibraryService = textCheckLibraryService;
}
、、、、、、
}
这里有几种加lombok的方式:
1、父类和子类都加上@AllArgsConstructor,但是子类的构造函数要求父类需要有个无参构造函数
2、父类和子类都加上@AllArgsConstructor,同时父类加上@NoArgsConstructor,但是会出现父类的final属性没有在无参构造时没有初始化的问题。
后续的探索持续跟进中。。。