2012-09-21 24 views
22

Tengo una clase Util con métodos estáticos. Dentro de mi clase Util, quiero usar beans de primavera, así que los incluí en mi clase de utilidades. Por lo que sé, no es una buena práctica usar los granos de primavera como campos estáticos. ¿Pero hay alguna forma de acceder a los granos de primavera en un método estático?Acceso a los granos de primavera en el método estático

Mi ejemplo:

public class TestUtils { 

    private static TestBean testBean; 

    public void setTestBean(TestBean testBean) { 
    TestUtils.testBean = testBean; 
    } 

    public static String getBeanDetails() { 
    return beanName = testBean.getDetails(); 
    } 
} 

he visto en muchos foros que esto no es una buena práctica. ¿Puede alguien mostrarme cómo puedo manejar este tipo de escenario?

Mi fichero de configuración:

<bean id="testUtils" class="com.test.TestUtils"> 
<property name="testBean" ref="testBean" /> 
</bean> 

Respuesta

0

El enfoque que usted ha descrito es lo que he visto que se utiliza para inyectar un grano de primavera en una clase de utilidad.

<bean id="testUtils" class="com.test.TestUtils"> 
<property name="testBean" ref="testBean" /> 
</bean> 

Otra opción es:

<bean name="methodInvokingFactoryBean" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
     <property name="staticMethod" value="TestUtils.setInstance"/> 
     <property name="arguments"> 
      <list> 
       <ref bean="testBean"/> 
      </list> 
     </property> 
</bean> 

con:

public class TestUtils { 

    private static testBean; 

    public static void setInstance(TestBean anInstance) { 
    testBean = anInstance; 
    } 

    public static String getBeanDetails() { 
    return testBean.getDetails(); 
    } 
} 

Más detalles son here y here

+0

No es claro para mí .. Se puede añadir PLZ la configuración testBean? – TechSpellBound

1

Así es como me inyecta desde la primavera para un campo estático.

<bean id="..." class="..."> 
<property name="fieldToBeInjected"> 
      <util:constant static-field="CONSTANT_FIELD" /> 
     </property> 
</bean> 

Quizás esto te ayude también.

10

El resultado de los métodos estáticos debe depender SOLAMENTE de los parámetros pasados ​​al método, por lo tanto, no es necesario llamar a ningún bean.

Si necesita llamar a otro bean, entonces su método debe ser un método miembro de un bean independiente.

Otras respuestas dan soluciones de trabajo, pero el hecho de que se puede hacer no significa que deba hacerse.

+0

Sí, creo que deberíamos usarlo como un parámetro en lugar de establecer directamente en la clase estática. Según los estándares, dice que no deberíamos usar el bean como estático, aunque podemos hacerlo de diferentes maneras, como se muestra en las respuestas anteriores. Gracias por la respuesta. – Rosh

+1

"El resultado de los métodos estáticos debería depender SOLAMENTE de los parámetros pasados ​​al método", ¡buen disparo! – Nickolas

9

también se puede implementar ApplicationContextAware interfaz, como esto:

@Component 
public class TestUtils implements ApplicationContextAware { 

    private static ApplicationContext ac; 

    public static String getBeanDetails() { 
    return beanName = ((TestBean) ac.getBean("testBean")).getDetails(); 
    } 

    @Override 
    public void setApplicationContext(ApplicationContext ac) { 
    this.ac = ac; 
    } 

} 
29

Mi enfoque es que el grano se desea acceder a aplicar o utilizar InitializingBean@PostConstruct, y que contiene una referencia estática a sí mismo.

Por ejemplo:

@Service 
public class MyBean implements InitializingBean { 
    private static MyBean instance; 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     instance = this; 
    } 

    public static MyBean get() { 
     return instance; 
    } 
} 

uso en su clase estática sería, por tanto, sólo puede ser:

MyBean myBean = MyBean.get(); 

De esta manera, no se requiere ninguna configuración XML, que no tienen que pasar el frijol en como un argumento constructor, y la persona que llama no necesita saber o preocuparse de que el bean esté conectado usando Spring (es decir, no hay necesidad de variables desordenadas ApplicationContext).

+0

slick - ¿Hay un buen lugar para encontrar la solución correcta para tales problemas recurrentes en Spring ..? –

1

Similar a la respuesta de @ nullPainter, pero hicimos lo siguiente. No se requiere lógica post-construcción.Simplemente establece el miembro estático directamente durante la inyección (en el método @Autowired).

@Service 
public class MyUtil { 

    private static MyManager myManager; 

    @Autowired(required = true) 
    public void setMyManager(MyManager manager) { 
     myManager = manager; 
    } 

    public static MyManager getMyManager() { 
     return myManager; 
    } 
} 
+0

No es necesario pasar el parámetro 'required = true' ya que ese es el valor predeterminado para' @ Autowired'. Tan solo '@Autowired public void setMyManager (Administrador de MyManager) { myManager = manager; } ' sería suficiente. – rumman0786

+0

requiere la anotación @Service que tiene poco sentido – rohanagarwal

0

Esto funciona para mí. En cierta clase:

import org.springframework.web.context.ContextLoader; 
import org.springframework.web.context.WebApplicationContext; 

WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext(); 
DataSource datasource = (DataSource)context.getBean("dataSourceDB_01");  

Y en mi configuración xml:

<bean id="dataSourceDB_01" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName"><value>${db.driver}</value></property>  
    <property name="url"><value>${db.url}</value></property> 
    <property name="username"><value>${db.username_seg}</value></property> 
    <property name="password"><value>${db.password_seg}</value></property> 
</bean> 

HTH

Cuestiones relacionadas