Подтвердить что ты не робот

Можете ли вы использовать @Autowired со статическими полями?

Есть ли способ использовать @Autowired со статическими полями. Если нет, есть ли другие способы сделать это?

4b9b3361

Ответ 1

Короче говоря, нет. Вы не можете автообновлять или вручную прокладывать статические поля в Spring. Вы должны будете написать свою собственную логику, чтобы сделать это.

Ответ 2

@Component("NewClass")
public class NewClass{
    private static SomeThing someThing;

    @Autowired
    public void setSomeThing(SomeThing someThing){
        NewClass.someThing = someThing;
    }
}

Ответ 3

@Autowired может использоваться с сеттерами, чтобы у вас мог быть сеттер, изменяющий статическое поле.

Только одно окончательное предложение... НЕ

Ответ 4

Инициируйте свой автопроводной компонент в методе @PostConstruct

@Component
public class TestClass {
   private static AutowiredTypeComponent component;

   @Autowired
   private AutowiredTypeComponent autowiredComponent;

   @PostConstruct
   private void init() {
      component = this.autowiredComponent;
   }

   public static void testMethod() {
      component.callTestMethod();
   }
}

Ответ 5

Создайте bean, который вы можете autwire, который инициализирует статическую переменную как побочный эффект.

Ответ 6

Вы можете достичь этого, используя XML-нотацию и MethodInvokingFactoryBean. Например, посмотрите здесь.

private static StaticBean staticBean;

public void setStaticBean(StaticBean staticBean) {
   StaticBean.staticBean = staticBean;
}

Вы должны стремиться использовать spring инъекцию, если это возможно, поскольку это рекомендуемый подход, но это не всегда возможно, поскольку я уверен, что вы можете себе представить, что не все можно вытащить из spring или вы, возможно, имеете дело с устаревшими системами.

Примечание: для этого подхода также может быть сложнее провести тестирование.

Ответ 7

Вы можете использовать ApplicationContextAware

@Component
public class AppContext implements ApplicationContextAware{
    public static ApplicationContext applicationContext;

    public AppBeans(){
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

затем

static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);

Ответ 8

Отказ от ответственности Это ни в коем случае не стандарт, и вполне может быть лучший весенний способ сделать это. Ни один из вышеприведенных ответов не затрагивает вопросы подключения открытого статического поля.

Я хотел сделать три вещи.

  1. Используйте пружину для "Autowire" (я использую @Value)
  2. Выставить публичное статическое значение
  3. Предотвратить изменение

Мой объект выглядит так

private static String BRANCH = "testBranch";

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

public static String BRANCH() {
    return BRANCH;
}

Мы уже отметили 1 и 2, как мы можем предотвратить вызовы сеттеру, поскольку мы не можем его скрыть.

@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;
    }
}

Этот аспект обернет все методы, начинающиеся с final, и выдаст ошибку, если они вызваны.

Я не думаю, что это особенно полезно, но если вы любите держать горох и морковь отдельно, это один из способов сделать это безопасно.

Важно Spring не вызывает ваши аспекты, когда вызывает функцию. Сделал это проще, к сожалению, я разработал логику, прежде чем понять это.

Ответ 9

private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);