回答:
つまり、いいえ。Springで静的フィールドを自動ワイヤリングまたは手動でワイヤリングすることはできません。これを行うには、独自のロジックを記述する必要があります。
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
someThing
静的にアクセスした場合に初期化されている保証はありません。NewClass.staticMethodWhichUsesSomething();
アプリの初期化前に使用するとNPEがスローされる可能性があります
Instance methods should not write to "static" fields (squid:S2696)
か?
@Autowired
静的フィールドを変更するセッターを使用できるように、セッターと共に使用できます。
最後に1つだけ提案...しないでください
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
@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();
}
}
Instance methods should not write to "static" fields (squid:S2696)
か?
これは、XML表記とを使用して実現できますMethodInvokingFactoryBean
。例については、こちらをご覧ください。
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
これは推奨されるアプローチであるため、可能な場合はスプリングインジェクションの使用を目指す必要がありますが、すべてがスプリングコンテナーから引き出せるわけではないか、レガシーシステムを扱っているとは限らないので、これは常に可能とは限りません。
この方法では、テストがさらに困難になる場合があります。
あなたは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);
自動配線の静的フィールド(または定数)は無視されるが、エラーも発生しないことを回答に追加したい:
@Autowired
private static String staticField = "staticValue";
免責事項これは決して標準的なものではなく、これを行うためのより良い春の方法が非常によくあるでしょう。上記の回答のいずれも、パブリック静的フィールドの配線の問題に対処していません。
私は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で始まるすべてのメソッドをラップし、それらが呼び出されるとエラーをスローします。
これは特に便利だとは思いませんが、ocdでエンドウ豆とニンジンを分離しておくのが好きな場合、これは安全に行う方法の1つです。
重要 Springは、関数を呼び出すときにアスペクトを呼び出しません。これを簡単にして、悪いことに私はそれを理解する前にロジックを考え出しました。
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);