Spring中如何向POJO类中注入属性?

假如在SpringBoot项目中有这么一个 需求,需要对接口返回的某个UserDto对象的手机号phone只显示后四位的处理,那么如何操作?

public class UserDto {
	private String name;
	private String phone;
	private String address;
}
  • 方式一

    public UserDto getUserInfo() {
    	 UserDto user = getUserDto;
      //在此处处理
      user.setPhone(xxxxx);
      return user;
    }
    

    在web-api层所有返回UserDto的接口中,在返回之前手动设置USerDto的phone属性只显示后四位。这种方法能实现功能,但是如果有十个接口返回了UserDto呢?或者一百个接口返回了UserDto呢?手动结果肯定是个体力活了

  • 方式二

    可以在UserDto中进行处理,如果在getter方法中处理会误伤到很多调用此方法的操作,显然不能再getter方法中处理。SpringBoot默认使用的json序列化框架Jackson为我们提供了一种方式:使用@JsonSerialize注解指定序列化方式。@JsonSerialize需要我们实现一个序列化器;

    public class MyJsonSerializer extends JsonSerializer<String> {
    
      //需要提供一个无参构造方法
      public MyJsonSerializer() {}
      
        @Override
        public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            //对value操作,使其只显示后四位
          	//...
        }
    }
    

    然后在UserDto中phone字段上为其指定序列化器:

    public class UserDto {
    	private String name;
    	@JsonSerialize(using = MyJsonSerializer.class)
    	private String phone;
    	private String address;
    }
    

    这样操作之后,phone字段就会按照MyJsonSerializer中的处理流程进行处理,就能轻松实现功能。

    那么问题来了,如果现在要求phone字段只显示后三位,又过一段需要显示后五位,怎么办?那这么也好办,我只需要在SpringBoot的配置文件中定一个显示的位数的phone.showCount属性,在MyJsonSerializer中根据该属性进行动态处理,完美解决。

    但是这样就有一个问题,如何在MyJsonSerializer中获取SpringBoot中配置文件中设置的参数呢?

    也许你又想到了@Value注解,可行吗?我们分析一下:

    首先JsonSerialize注解中using属性需要的一个Class,而@Value只能在Spring容器管理的对象中才有效,也就是说需要把MyJsonSerializer实例化一个Bean并注入到Ioc容器中,这样才能使用@Value注解注入配置文件中的值。但是@JsonSerialize(using = MyJsonSerializer.class)中只接收一个Class,不接受一个Bean对象,所以如果只简单的通过@ValueMyJsonSerializer中注入配置文件中的值是行不通的。

    那么该如何解决这个问题呢?

    因为@JsonSerialize(using = MyJsonSerializer.class)接收的是一个Class对象,那我们能把配置文件中的参数作为MyJsonSerializer的一个静态属性注入进去吗?答案是否定的,@Value不能向静态成员变量注入属性。

    现在的问题就变成了如何向未被Spring容器管理的POJO对象中注入属性?

    一个曲线救国的方法:

    public class MyJsonSerializer extends JsonSerializer<String> {
      
      //添加一个静态属性
      private static Integer showCount;
      
      //添加一个接受一个`Integer showCounc`的构造方法
      public MyJsonSerializer(Integer c) {
        showCount = c;
      }
      
    }
    

    然后只需要在外部主动的将配置文件的参数通过带参构造方法传递进来即可。

    @Configuration
    public class MyConfig {
      
     //因为当前类为配置类,所以在这里肯定能够获取到配置文件中的变量的 
      @Value("${phone.showCount}")
    	private static Integer showCount;
      
      //注入此Bean的目的并不是为了使用该Bean,而是为了将showCount变量传递给 MyJsonSerializer 类。
      //一个类对象在JVM中只有单独的一份,所以在任何地方使用 MyJsonSerializer 都能获得它的showCount属性。
      @Bean
      public MyJsonSerializer jsonSerializer() {
        return new MyJsonSerializer(showCount);
      }
      
    }
    

    所以,至此已经成功的将Spring配置文件的值注入到了一个非Ioc容器管理的对象之中去了。@Autowired同理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值