BeanFactoryPostProcessor

执行顺序

BeanFactoryPostProcessor —> 普通Bean构造方法 —> 设置依赖或属性 —> @PostConstruct —> InitializingBean —> initMethod

此案例是 将配置文件里的一些敏感数据进行加密后,启动项目后,spring容器会优先执行 BeanFactoryPostProcessor 子类流程,在子类流程中再将敏感数据进行解密,起到保密的效果

一、正常mvc流程

1、entity

@Data
public class Person {
    private Integer id;
    private String name;
    private Integer age;
}

2、controller

@RestController
public class PersonController {

    @Autowired
    private PersonService personService;

    @GetMapping("/person")
    public List<Person> selectAll(){
        List<Person> persons = this.personService.selectPersons();
        return persons;
    }

}

3、service

public interface PersonService {

    List<Person> selectPersons();

}

@Service
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonMapper personMapper;

    @Override
    public List<Person> selectPersons() {
        List<Person> persons = this.personMapper.selectPersons();
        return persons;
    }
}

4、mapper

@Mapper
@Repository
public interface PersonMapper {

    List<Person> selectPersons();

}

5、mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lian.beanfactorypostprocessor.mapper.PersonMapper">
    <select id="listPerson" resultType="com.lian.beanfactorypostprocessor.entity.Person">
		SELECT
            id,name,age
        FROM
            person
	</select>

    <select id="selectPersons" resultType="com.lian.beanfactorypostprocessor.entity.Person">
        SELECT
            id,name,age
        FROM
            person
    </select>
</mapper>

6、yml

server:
  port: 8888
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/websocketone?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone = GMT
      username: root
      # root加密后的密码
      password: GQlo/lcKiXIEqDtzF3Ds2w==

mybatis:
  mapper-locations: classpath:mapper/*.xml

7、扫描spring bean

@ComponentScan(basePackages = {"com.lian"})
@Configuration
public class Configurator {
}

二、BeanFactoryPostProcessor子类

1、加解密

//加解密类
public class EnDeCode {

    private static final String ALGRITHM_SHA1PRNG = "SHA1PRNG";
    private static final String KEY_SHA = "AES";

    //加密
    public static String encode(String context,String secretKey) throws Exception{
        Key key = getKey(secretKey);

        Cipher cipher = Cipher.getInstance(KEY_SHA);
        cipher.init(Cipher.ENCRYPT_MODE,key);
        byte[] bytes = cipher.doFinal(context.getBytes());

        BASE64Encoder encoder = new BASE64Encoder();
        String encode = encoder.encode(bytes);

        return encode;
    }


    //解密
    public static String decode(String context, String secretKey) throws Exception{
        Key key = getKey(secretKey);

        Cipher cipher = Cipher.getInstance(KEY_SHA);
        cipher.init(Cipher.DECRYPT_MODE,key);

        BASE64Decoder decoder = new BASE64Decoder();
        byte[] bytes = decoder.decodeBuffer(context);
        byte[] aFinal = cipher.doFinal(bytes);
        String res = new String(aFinal);
        return res;
    }

    //获取key
    public static Key getKey(String secretKey) throws Exception{
        SecureRandom secureRandom = SecureRandom.getInstance(ALGRITHM_SHA1PRNG);
        secureRandom.setSeed(secretKey.getBytes());
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_SHA);
        keyGenerator.init(secureRandom);
        SecretKey key = keyGenerator.generateKey();
        return key;
    }

    public static void main(String[] args) throws Exception {
        //加密
        String encode = encode("root", KEY_SHA);
        System.out.println("encode : "+encode); //GQlo/lcKiXIEqDtzF3Ds2w==

        //解密
        String decode = decode("GQlo/lcKiXIEqDtzF3Ds2w==", KEY_SHA);
        System.out.println("decode : "+decode);
    }
}

2、BeanFactoryPostProcessor子类实现

@Component
public class DefineBeanFactory implements EnvironmentAware, BeanFactoryPostProcessor {

    private static final String KEY_SHA = "AES";
    private ConfigurableEnvironment configurableEnvironment;

    @Override
    public void setEnvironment(Environment environment) {
        this.configurableEnvironment = (ConfigurableEnvironment)environment;
    }

    //spring容器会先走此方法流程,再去初始化其他的bean
    //ConfigurableListableBeanFactory 此子类拥有父类的几十个方法,是beanFactory的主要子类
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        MutablePropertySources propertySources = configurableEnvironment.getPropertySources();
        List<PropertySource<LinkedHashMap>> mapList = StreamSupport.stream(propertySources.spliterator(), false)
                .filter(o -> o instanceof OriginTrackedMapPropertySource)
                .map(s -> (PropertySource<LinkedHashMap>) s)
                .collect(Collectors.toList());
        for (PropertySource<LinkedHashMap> source : mapList) {
            LinkedHashMap map = source.getSource();
            try {
                if (map.containsKey("spring.datasource.druid.password")){
                    String value = String.valueOf(map.get("spring.datasource.druid.password"));
                    //解密
                    String decodePassword = EnDeCode.decode(value, KEY_SHA);
                    map.put("spring.datasource.druid.password",decodePassword);
                }else {
                    continue;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值