Spring的InitializingBean

董弘新
2023-12-01

之前知道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来给别的静态数据结构塞值,整个过程可以方便我们扩展代码,感觉这种方式写代码更符合开闭原则。

 类似资料: