2012-07-04 9 views
55

Sé que esto puede parecerse a una pregunta anterior pero me enfrenta un problema diferente aquí.Cómo hacer que el resorte inyecte valor en un campo estático

Tengo una clase de utilidad que solo tiene métodos estáticos. No lo hago y no tomaré una instancia de él.

public class Utils{ 
    private static Properties dataBaseAttr; 
    public static void methodA(){ 

    } 

    public static void methodB(){ 

    } 
} 

Ahora necesito primavera para llenar dataBaseAttr con base de datos de atributos Properties.Spring de configuración es:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> 

<util:properties id="dataBaseAttr" 
     location="file:#{classPathVariable.path}/dataBaseAttr.properties" /> 
</beans> 

ya lo he hecho en otros granos, pero el problema aquí en esta clase (Utilidades) no es un frijol, y si lo hago un frijol, nada cambia, todavía no puedo usar la variable ya que la clase no se instanciará y la variable siempre es igual a nulo.

Respuesta

93

Tiene dos posibilidades:

  1. colocador no estático de la propiedad/campo estático;
  2. usando org.springframework.beans.factory.config.MethodInvokingFactoryBean para invocar un setter estático.

En la primera opción tiene un bean con un setter regular pero en lugar de establecer una propiedad de instancia, establece la propiedad/campo estático.

public void setTheProperty(Object value) { 
    foo.bar.Class.STATIC_VALUE = value; 
} 

pero con el fin de hacer esto es necesario tener una instancia de un bean que se exponga el colocador (que es más como una solución ).

En el segundo caso se haría de la siguiente manera:

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="staticMethod" value="foo.bar.Class.setTheProperty"/> 
    <property name="arguments"> 
     <list> 
      <ref bean="theProperty"/> 
     </list> 
    </property> 
</bean> 

En que caso de que se añada un nuevo colocador en la clase Utils:

public static setDataBaseAttr(Properties p) 

y en su contexto lo configurará con el enfoque ejemplificado anteriormente, más o menos como:

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="staticMethod" value="foo.bar.Utils.setDataBaseAttr"/> 
    <property name="arguments"> 
     <list> 
      <ref bean="dataBaseAttr"/> 
     </list> 
    </property> 
</bean> 
+0

Muchas gracias, realmente salvaste mi día. –

+0

¡eres bienvenido! –

+0

No probé la primera solución porque no la entendía bien. Intenté la segunda solución y funcionó muy bien. –

20

que he tenido un requisito similar: que necesitaba para inyectar un grano repositorio de primavera gestionados en mi Person clase de entidad ("entidad", como en "algo con una identidad", por ejemplo, una entidad JPA) . Una instancia Person tiene amigos, y para que esta instancia Person devuelva sus amigos, deberá delegar en su repositorio y consultar allí a sus amigos.

@Entity 
public class Person { 
    private static PersonRepository personRepository; 

    @Id 
    @GeneratedValue 
    private long id; 

    public static void setPersonRepository(PersonRepository personRepository){ 
     this.personRepository = personRepository; 
    } 

    public Set<Person> getFriends(){ 
     return personRepository.getFriends(id); 
    } 

    ... 
} 

.

@Repository 
public class PersonRepository { 

    public Person get Person(long id) { 
     // do database-related stuff 
    } 

    public Set<Person> getFriends(long id) { 
     // do database-related stuff 
    } 

    ... 
} 

Entonces, ¿cómo me inyecto que PersonRepository Singleton en el campo estático de la clase Person?

Creé un @Configuration, que se recogió en Spring ApplicationContext tiempo de construcción.Este @Configuration se inyecta con todos los beans que necesito para inyectar como campos estáticos en otras clases. Luego, con una anotación @PostConstruct, atrapo un gancho para hacer toda la lógica de inyección de campo estático.

@Configuration 
public class StaticFieldInjectionConfiguration { 

    @Inject 
    private PersonRepository personRepository; 

    @PostConstruct 
    private void init() { 
     Person.setPersonRepository(personRepository); 
    } 
} 
+0

¿Cómo es posible que pueda acceder a esto desde un método estático? ¡No creo que esto sea posible en absoluto! ¿No debería ser Person.personRepository = personRepository? –

+3

@JonasGeiregat es posible ya que el método es estático y está accediendo a la variable estática –

+3

Me pregunto cómo alguien hace referencia a una variable estática a través de 'esto' en un contexto estático? – Kripz

Cuestiones relacionadas