Можете ли вы использовать @Autowired со статическими полями? - PullRequest
117 голосов
/ 19 июня 2009

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

Ответы [ 9 ]

100 голосов
/ 19 июня 2009

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

91 голосов
/ 13 мая 2011
@Component("NewClass")
public class NewClass{
    private static SomeThing someThing;

    @Autowired
    public void setSomeThing(SomeThing someThing){
        NewClass.someThing = someThing;
    }
}
63 голосов
/ 20 июня 2009

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

Только одно последнее предложение ... НЕ

8 голосов
/ 26 декабря 2017

Инициируйте свой компонент с автопроводкой в ​​методе @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 голосов
/ 20 июня 2009

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

4 голосов
/ 22 июня 2009

Этого можно добиться, используя XML-нотацию и MethodInvokingFactoryBean. Для примера посмотрите здесь .

private static StaticBean staticBean;

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

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

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

0 голосов
/ 22 июня 2019

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

Я хотел выполнить три вещи.

  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 не вызывает ваши аспекты при вызове функции. Сделал это проще, к сожалению, я разработал логику, прежде чем понять это.

0 голосов
/ 14 июня 2019

Вы можете использовать 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);
0 голосов
/ 26 марта 2019
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...