之前知道spring的InitializingBean,但是没怎么关注,最近在一次代码改造的使用工厂模式和策略模式的情况下,发现InitializingBean。
InitializingBean是spring为bean的初始化提供了一种新的方式,里面只有一个方法afterPropertiesSet,作用就是实现这个接口或者实现了继承InitializingBean的方法的bean都要执行这个方法。
举了例子:
@Component
import org.springframework.beans.factory.InitializingBean;
public class TestInitializingBean implements InitializingBean{
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(" 张鹏真的很帅 InitializingBean");
}
public void testInit(){
System.out.println("张鹏真的很帅");
}
}
调起spring程序会打印出
张鹏真的很帅 InitializingBean
这个单个看起来没啥用,但是结合实际情况就不一样
比如说我想在下面这个工厂类里面的map添加值
@Component
public class ValidAssetByTypeFactory {
private static Map<String,ValidateAssetService> validAssetTypeMap = new HashMap<>();
/**
* 用来维护根据类型验证资产的规则的map
* @param type
* @return
*/
public static ValidateAssetService getInvokeStrategyMap(String type){
return validAssetTypeMap.get(type);
}
}
实际上这个validAssetTypeMap ,这个map是静态的你要是真要想往里面塞值的话,只能在这个类下面写个静态方法或者一个一个静态块往这个map里面塞值,类似这样:
static
{
validAssetTypeMap.put ("A","AStragey");
validAssetTypeMap.put ("B","BStragey");
validAssetTypeMap.put ("C","CStragey");
}
但是有了这个InitializingBean,可以这么玩:
(1)我先实现一个InitializingBean的接口
public interface ValidateAssetService extends InitializingBean {
Result<List<DetailsAppAsset>> validateAssetByType(List<AssetDO> assetDOList,String type);
}
(2)我在这个工厂类里面添加一个静态的方法,用来往这个静态map添加值
注意这个register方法
public class ValidAssetByTypeFactory {
private static Map<String,ValidateAssetService> validAssetTypeMap = new HashMap<>();
/**
* 用来维护根据类型验证资产的规则的map
* @param type
* @return
*/
public static ValidateAssetService getInvokeStrategyMap(String type){
return validAssetTypeMap.get(type);
}
/**
* 注册(创建实现类直接注册即可,不需要在该类放进策略map里面)
* @param type
* @param validateAssetService
*/
public static void register(String type, ValidateAssetService validateAssetService){
if(StringUtil.isEmpty(type)||null == validateAssetService){
return;
}
validAssetTypeMap.put(type,validateAssetService);
}
}
(3)由于上一步给我们往静态map添加值留了一个口子,我们要利用InitializingBean初始化会执行afterPropertiesSet的特性在spring执行起来的时候直接调用这个方法往静态map里面塞值。
注意这个afterPropertiesSet方法的实现:
@Component
public class RepairAssetValidate implements ValidateAssetService {
@Override
public Result<List<DetailsAppAsset>> validateAssetByType(List<AssetDO> assetDOList, String type) {
if( CollUtil.isEmpty(assetDOList) ){
return resultCreator.create(AssetErrorCode.ASSET_NOT_EXISTS, EntityConverter.convertList(assetDOList, DetailsAppAsset.class));
}
for(AssetDO assetDO : assetDOList){
if( assetDO.getQuoteOrderId() != null ){
return resultCreator.create(AssetValidErrorCode.ASSET_IN_OTHER_OPERATOR,"资产已被"+ QuoteOrderType.getQuoteOrderType(assetDO.getQuoteOrderType())+"引用" ,EntityConverter.convertList(assetDOList, DetailsAppAsset.class));
}
}
return resultCreator.create(ErrorCode.SUCCESS, EntityConverter.convertList(assetDOList, DetailsAppAsset.class));
}
@Override
public void afterPropertiesSet() throws Exception {
ValidAssetByTypeFactory.register(AssetValidateType.REPAIR.getValue(),this);
}
@Autowired
private ResultCreator resultCreator;
}
这样我们就可以在别的地方借用spring的InitializingBean来给别的静态数据结构塞值,整个过程可以方便我们扩展代码,感觉这种方式写代码更符合开闭原则。