Jawaban:
Singkatnya, tidak. Anda tidak dapat autowire atau secara manual kawat bidang statis di Spring. Anda harus menulis sendiri logika Anda untuk melakukan ini.
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
someThingtelah diinisialisasi jika diakses secara statis: NewClass.staticMethodWhichUsesSomething();mungkin melempar NPE jika digunakan sebelum inisialisasi aplikasi
Instance methods should not write to "static" fields (squid:S2696)?
@Autowired dapat digunakan dengan setter sehingga Anda bisa memiliki setter memodifikasi bidang statis.
Hanya satu saran terakhir ... JANGAN
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Masuk komponen autowired Anda dalam metode @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)?
Anda dapat mencapai ini menggunakan notasi XML dan MethodInvokingFactoryBean. Sebagai contoh, lihat di sini .
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
Anda harus berusaha menggunakan injeksi pegas di mana mungkin karena ini adalah pendekatan yang direkomendasikan tetapi ini tidak selalu mungkin karena saya yakin Anda bisa membayangkan karena tidak semuanya bisa ditarik dari wadah pegas atau Anda mungkin berurusan dengan sistem warisan.
Catatan pengujian juga bisa lebih sulit dengan pendekatan ini.
Ingin menambahkan jawaban bahwa bidang statis perkabelan otomatis (atau konstan) akan diabaikan, tetapi juga tidak akan membuat kesalahan:
@Autowired
private static String staticField = "staticValue";
Anda dapat menggunakan ApplicationContextAware
@Component
public class AppContext implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public AppBeans(){
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
kemudian
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
Penafian Ini tidak berarti standar dan mungkin ada cara musim semi yang lebih baik untuk melakukan ini. Tak satu pun dari jawaban di atas mengatasi masalah perkabelan bidang statis publik.
Saya ingin menyelesaikan tiga hal.
Objek saya terlihat seperti ini
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
Kami telah memeriksa 1 & 2 sekarang bagaimana cara mencegah panggilan ke setter, karena kami tidak dapat menyembunyikannya.
@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;
}
}
Aspek ini akan membungkus semua metode mulai dengan final dan melemparkan kesalahan jika mereka dipanggil.
Saya tidak berpikir ini sangat berguna, tetapi jika Anda oCD dan ingin menjaga Anda kacang polong dan wortel dipisahkan ini adalah salah satu cara untuk melakukannya dengan aman.
Pegas Penting tidak memanggil aspek Anda saat memanggil fungsi. Membuat ini lebih mudah, buruk saya mengerjakan logika sebelum mencari tahu itu.
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);