set “systems” property in controller and access th

2019-09-02 20:46发布

问题:

I am working on internationalizing the database. My task is internationalize database fields with least amount of changes possible. My question is- how can I set properties to a thread from controller method and access that property from my aspect. System.setProperties() is obviously not thread safe.

class Title {
    ...
    private String description;
    ...
}

@Entity
Class Language {
    ...
    private String name;
    ...

    public static String fingLanguageByName(String name) {
        ...
        return l;
    }
}

@Entity
Class InternationalizedTitle {
    ...
    private Title title;
    private String description;
    private Language language;
    ...
    public static String findDescriptionByTitleAndDate(Title t, Language l) {
        ...
        return d;
    }
    ...
}

@Controller
class TitleController {
    ...
    public TitleResponse getTitle(HttpServletRequest request, HttpServletResponse response) {
        if (request.isComingFromFrance()){


            ***System.setProperty("language", "French");***

        }
        return titleService.getTitleResponse(request);
    }
    ...
}

@Aspect
InternationalizationAspect {
    ...
    @Around("execution(* com.*.*.*.Title.getDescription(..))")
    public String getInternationalizedTitleDescription(ProceedingJoinPoint joinPoint) throws Throwable {
        ***String language = System.getProperty("language");***
        if (language == null) {
            return joinPoint.proceed();
        } else {
            Title t = (Title) joinPoint.getTarget();
            return InternationalizedTitle.findDescriptionByTitleAndDate(t,Language.findLanguageByName(name))
        }
    }
    ...
}

回答1:

If you're working with the single thread model, you can use a ThreadLocal. Either use a class with a public static final ThreadLocal field or make a singleton bean with an instance field.

What you put in the ThreadLocal is entirely up to you. If you only need a String value for the language, you could simply put a String value.

private ThreadLocal<String> language = new ThreadLocal<>();

Each thread will always be accessing its own object.