Respuestas:
En resumen, no. No puede conectar automáticamente o cablear manualmente los campos estáticos en Spring. Tendrás que escribir tu propia lógica para hacer esto.
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
someThing
se haya inicializado si se accede estáticamente: NewClass.staticMethodWhichUsesSomething();
podría arrojar un NPE si se usa antes de la inicialización de la aplicación
Instance methods should not write to "static" fields (squid:S2696)
?
@Autowired
puede usarse con setters para que pueda tener un setter modificando un campo estático.
Solo una sugerencia final ... NO
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Inicie su componente con cable automático en el método @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)
?
Puede lograr esto utilizando la notación XML y el MethodInvokingFactoryBean
. Para un ejemplo mira aquí .
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
Debe intentar utilizar la inyección de resorte siempre que sea posible, ya que este es el enfoque recomendado pero esto no siempre es posible, ya que estoy seguro de que se puede imaginar, ya que no todo se puede extraer del contenedor de resorte o tal vez se trate de sistemas heredados.
Tenga en cuenta que las pruebas también pueden ser más difíciles con este enfoque.
Quería agregar a las respuestas que el campo estático de cableado automático (o constante) se ignorará, pero tampoco creará ningún error:
@Autowired
private static String staticField = "staticValue";
Puedes usar ApplicationContextAware
@Component
public class AppContext implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public AppBeans(){
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
luego
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
Descargo de responsabilidad Esto de ninguna manera es estándar y bien podría haber una mejor manera de hacerlo. Ninguna de las respuestas anteriores aborda los problemas de cableado de un campo estático público.
Quería lograr tres cosas.
Mi objeto se ve así
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
Ya hemos marcado 1 y 2, ¿cómo evitamos las llamadas al emisor, ya que no podemos ocultarlo?
@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;
}
}
Este aspecto envolverá todos los métodos que comienzan con final y arrojará un error si se llaman.
No creo que esto sea particularmente útil, pero si está ocd y desea mantener los guisantes y las zanahorias separados, esta es una forma de hacerlo de manera segura.
Importante Spring no llama a sus aspectos cuando llama a una función. Lo hice más fácil, para mal, resolví la lógica antes de resolverlo.
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);