Can you use @Autowired with static fields?

后端 未结 11 1346
臣服心动
臣服心动 2020-11-22 13:15

Is there some way to use @Autowired with static fields. If not, are there some other ways to do this?

相关标签:
11条回答
  • 2020-11-22 13:42

    You can use ApplicationContextAware

    @Component
    public class AppContext implements ApplicationContextAware{
        public static ApplicationContext applicationContext;
    
        public AppBeans(){
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    }
    

    then

    static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
    
    0 讨论(0)
  • 2020-11-22 13:43

    @Autowired can be used with setters so you could have a setter modifying an static field.

    Just one final suggestion... DON'T

    0 讨论(0)
  • 2020-11-22 13:43

    Wanted to add to answers that auto wiring static field (or constant) will be ignored, but also won't create any error:

    @Autowired
    private static String staticField = "staticValue";
    
    0 讨论(0)
  • 2020-11-22 13:43

    Disclaimer This is by no means standard and there could very well be a better spring way of doing this. None of the above answers address the issues of wiring a public static field.

    I wanted to accomplish three things.

    1. Use spring to "Autowire" (Im using @Value)
    2. Expose a public static value
    3. Prevent modification

    My object looks like this

    private static String BRANCH = "testBranch";
    
    @Value("${content.client.branch}")
    public void finalSetBranch(String branch) {
        BRANCH = branch;
    }
    
    public static String BRANCH() {
        return BRANCH;
    }
    

    We have checked off 1 & 2 already now how do we prevent calls to the setter, since we cannot hide it.

    @Component
    @Aspect
    public class FinalAutowiredHelper {
    
    @Before("finalMethods()")
    public void beforeFinal(JoinPoint joinPoint) {
        throw new FinalAutowiredHelper().new ModifySudoFinalError("");
    }
    
    @Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")
    public void finalMethods() {}
    
    
    public class ModifySudoFinalError extends Error {
        private String msg;
    
        public ModifySudoFinalError(String msg) {
            this.msg = msg;
        }
    
        @Override
        public String getMessage() {
            return "Attempted modification of a final property: " + msg;
        }
    }
    

    This aspect will wrap all methods beginning with final and throw an error if they are called.

    I dont think this is particularly useful, but if you are ocd and like to keep you peas and carrots separated this is one way to do it safely.

    Important Spring does not call your aspects when it calls a function. Made this easier, to bad I worked out the logic before figuring that out.

    0 讨论(0)
  • 2020-11-22 13:45

    Generally, setting static field by object instance is a bad practice.

    to avoid optional issues you can add synchronized definition, and set it only if private static Logger logger;

    @Autowired
    public synchronized void setLogger(Logger logger)
    {
        if (MyClass.logger == null)
        {
            MyClass.logger = logger;
        }
    }
    

    :

    0 讨论(0)
提交回复
热议问题