In the recent work, I got a very practical note to share with you.

Pain points

Done WeChat or pay treasure to pay children’s shoes, may be encountered this problem, is to fill in payment results callback, is in the pay after success, alipay, according to the address we give to our notice, inform us whether the user pay successful, if successful we will go to deal with the following the corresponding business logic, if the test service, Then we need to fill in the callback address of the test service. If it is posted online, we need to change it to the online address.

For the above scenarios, we generally carry out a dynamic configuration in the following way, which does not need to be changed every time to prevent problems.

public class PayTest {

    @Value("${spring.profiles.active}")
    private String environment;

    public Object notify(HttpServletRequest request) {

        if ("prod".equals(environment)) {// Official environment}else if ("test".equals(environment)) {// Test environment}return "SUCCESS"; }}Copy the code

The above code looks fine, but how can we move bricks like this, the posture is not right!

Question:

The scalability is poor. If we need to use this parameter in other places, shall we use the annotation @value to get it again? If one day our leader suddenly says, “test” looks too low. So should we correct all the tests in the project? If there are less tests, it is ok; if there are more tests, we are afraid that it is not cold.

So can we make these configuration parameters a global static variable, so we can just drink it, and even if I do change it, I only need to change one thing.

Pay attention to the hole

If you’re going to be static, you’re going to pack your bags and leave. Static = null; static = null; static = null;

@ PostConstruct annotations

So if you name the problem, there must be a solution, or you think I’m playing with you.

First, this annotation is provided by Java and is used to modify a non-static void method. It runs when the server loads the Servlet and only once.

Modification:

@Component
public class SystemConstant {

    public static String surroundings;

    @Value("${spring.profiles.active}")
    public String environment;

    @PostConstruct
    public void initialize() {
        System.out.println("Initialize environment..."); surroundings = this.environment; }}Copy the code

Results:

We can see that the initialization takes place at project startup time

At this point we can check whether the current running environment is test or formal, so that we can do dynamic configuration

Finally want to say

In fact, this annotation is far more useful than that. For example, I wrote the Redis utility class with the RedisTemplate operation on Redis. As a result, the method cannot be modified static, and the Redis utility class can only be injected into the container and then called. Using this annotation is the perfect way to solve this awkward problem. Here’s the code.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @ClassName RedisUtil
 * @Description TODO
 * @Auther bingfeng
 * @Date 2019/7/4/004 17:14
 * @Version 1.0
 */
@Component
public class RedisUtil {

    private static RedisTemplate<Object, Object> redisTemplates;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @PostConstruct
    public void initialize() { redisTemplates = this.redisTemplate; } /** * add element ** @param key * @param value */ public static voidset(Object key, Object value) {

        if (key == null || value == null) {
            return; } redisTemplates.opsForValue().set(key, value); }}Copy the code