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.
Cuando encuentre que el código antiguo hace esto, es un antipatrón. Entrecierra los ojos, inclina la cabeza y encuentra una mejor manera de resolver el problema. Estaras contento de haberlo hecho.
Joseph Lust
2
esta respuesta también es útil en Spring's@AutoWired
¿Alguna idea de cómo puedo usar este enfoque al inicializar un repositorio?
kiedysktos
3
La desventaja: no hay garantía de que someThingse 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
Neeraj
¿Se puede evitar la advertencia de Instance methods should not write to "static" fields (squid:S2696)?
user7294900
@ user7294900: deshabilite esta advertencia solo para este caso muy específico.
izogfif
@izogfif sigue siendo un problema si elijo esta solución en casos y clases
generales
67
@Autowired puede usarse con setters para que pueda tener un setter modificando un campo estático.
Hmmm ... mi sensación acerca de por qué no se recomienda es porque la instancia estática en la clase está más allá del control de la primavera. Una vez inyectado, el campo estático es la referencia para todas las instancias de objetos de la clase correspondiente (circundante). Sin embargo, podría ser exactamente lo que se espera que este comportamiento a suceder, por tanto, podría ser visto como un error o de una pieza ...
Matthaeus
1
Sí @matthaeus, es exactamente la característica que esperaba cuando necesitaba acceder a org.springframework.core.env.Environment:@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
user1767316
@JonLorusso y todo Porque cuando el cargador de clases carga los valores estáticos, el contexto Spring aún no es necesario cargar. Por lo tanto, el cargador de clases no inyectará correctamente la clase estática en el bean y fallará. Respuesta proporcionada por Andrea T
Jeril Kuruvila
14
Inicie su componente con cable automático en el método @PostConstruct
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.
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.
Ya hemos marcado 1 y 2, ¿cómo evitamos las llamadas al emisor, ya que no podemos ocultarlo?
@Component@AspectpublicclassFinalAutowiredHelper{@Before("finalMethods()")publicvoid beforeFinal(JoinPoint joinPoint){thrownewFinalAutowiredHelper().newModifySudoFinalError("");}@Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")publicvoid finalMethods(){}publicclassModifySudoFinalErrorextendsError{privateString msg;publicModifySudoFinalError(String msg){this.msg = msg;}@OverridepublicString 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.
Si bien este código puede resolver la pregunta, incluir una explicación de cómo y por qué esto resuelve el problema realmente ayudaría a mejorar la calidad de su publicación, y probablemente resultaría en más votos positivos. Recuerde que está respondiendo la pregunta para los lectores en el futuro, no solo la persona que pregunta ahora. Por favor, editar su respuesta para agregar explicaciones y dar una indicación de lo que se aplican limitaciones y supuestos.
pitido doble el
Creo que esta respuesta puede no necesitar ninguna explicación en absoluto.
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.
fuente
@AutoWired
fuente
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ónInstance 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
fuente
@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
fuente
Instance methods should not write to "static" fields (squid:S2696)
?Cree un bean que pueda conectar automáticamente que inicializará la variable estática como un efecto secundario.
fuente
Puede lograr esto utilizando la notación XML y el
MethodInvokingFactoryBean
. Para un ejemplo mira aquí .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.
fuente
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:
fuente
Puedes usar ApplicationContextAware
luego
fuente
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í
Ya hemos marcado 1 y 2, ¿cómo evitamos las llamadas al emisor, ya que no podemos ocultarlo?
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.
fuente
fuente