Câu trả lời:
Tóm lại, không. Bạn không thể tự động hoặc dây thủ công các trường tĩnh trong Spring. Bạn sẽ phải viết logic của riêng bạn để làm điều này.
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
someThing
đã được khởi tạo nếu được truy cập tĩnh: NewClass.staticMethodWhichUsesSomething();
có thể ném NPE nếu được sử dụng trước khi khởi tạo ứng dụng
Instance methods should not write to "static" fields (squid:S2696)
?
@Autowired
có thể được sử dụng với setters để bạn có thể có một setter sửa đổi trường tĩnh.
Chỉ cần một đề nghị cuối cùng ... ĐỪNG
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Khởi tạo thành phần tự động của bạn trong phương thức @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)
?
Bạn có thể đạt được điều này bằng cách sử dụng ký hiệu XML và MethodInvokingFactoryBean
. Ví dụ nhìn vào đây .
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
Bạn nên đặt mục tiêu sử dụng thuốc tiêm mùa xuân khi có thể vì đây là cách tiếp cận được khuyến nghị nhưng điều này không phải lúc nào cũng có thể vì tôi chắc chắn bạn có thể tưởng tượng vì không phải mọi thứ đều có thể được kéo từ thùng chứa lò xo hoặc bạn có thể xử lý các hệ thống cũ.
Kiểm tra lưu ý cũng có thể khó khăn hơn với phương pháp này.
Bạn có thể sử dụng ApplicationContextAware
@Component
public class AppContext implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public AppBeans(){
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
sau đó
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
Muốn thêm vào câu trả lời rằng trường tĩnh tự động (hoặc hằng số) sẽ bị bỏ qua, nhưng cũng sẽ không tạo ra bất kỳ lỗi nào:
@Autowired
private static String staticField = "staticValue";
Tuyên bố miễn trừ trách nhiệm Đây không phải là tiêu chuẩn và rất có thể là một cách tốt hơn để làm điều này. Không có câu trả lời nào ở trên giải quyết các vấn đề nối dây trường tĩnh công cộng.
Tôi muốn hoàn thành ba điều.
Đối tượng của tôi trông như thế này
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
Chúng tôi đã kiểm tra 1 & 2 ngay bây giờ để làm thế nào để chúng tôi ngăn chặn các cuộc gọi đến setter, vì chúng tôi không thể ẩn nó.
@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;
}
}
Khía cạnh này sẽ bao bọc tất cả các phương thức bắt đầu bằng cuối cùng và đưa ra lỗi nếu chúng được gọi.
Tôi không nghĩ rằng điều này đặc biệt hữu ích, nhưng nếu bạn là ocd và muốn giữ cho bạn tách đậu và cà rốt thì đây là một cách để làm điều đó một cách an toàn.
Mùa xuân quan trọng không gọi các khía cạnh của bạn khi nó gọi một chức năng. Làm cho điều này dễ dàng hơn, xấu đến mức tôi đã tìm ra logic trước khi tìm ra điều đó.
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);