问题
I know this may looks like a previously asked question but I\'m facing a different problem here.
I have a utility class that has only static methods. I don\'t and I won\'t take an instance from it.
public class Utils{
private static Properties dataBaseAttr;
public static void methodA(){
}
public static void methodB(){
}
}
Now I need Spring to fill dataBaseAttr with database attributes Properties.Spring config is:
<?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>
I already done it in other beans but the problem here in this class (Utils) isn\'t a bean, And if I make it a bean nothing changes I still can\'t use the variable since the class will not be instantiated and variable always equals null.
回答1:
You have two possibilities:
- non-static setter for static property/field;
- using org.springframework.beans.factory.config.MethodInvokingFactoryBean to invoke a static setter.
In the first option you have a bean with a regular setter but instead setting an instance property you set the static property/field.
public void setTheProperty(Object value) {
foo.bar.Class.STATIC_VALUE = value;
}
but in order to do this you need to have an instance of a bean that will expose this setter (its more like an workaround).
In the second case it would be done as follows:
<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>
On you case you will add a new setter on the Utils
class:
public static setDataBaseAttr(Properties p)
and in your context you will configure it with the approach exemplified above, more or less like:
<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>
回答2:
I've had a similar requirement: I needed to inject a Spring-managed repository bean into my Person
entity class ("entity" as in "something with an identity", for example an JPA entity). A Person
instance has friends, and for this Person
instance to return its friends, it shall delegate to its repository and query for friends there.
@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
}
...
}
So how did I inject that PersonRepository
singleton into the static field of the Person
class?
I created a @Configuration
, which gets picked up at Spring ApplicationContext construction time. This @Configuration
gets injected with all those beans that I need to inject as static fields into other classes. Then with a @PostConstruct
annotation, I catch a hook to do all static field injection logic.
@Configuration
public class StaticFieldInjectionConfiguration {
@Inject
private PersonRepository personRepository;
@PostConstruct
private void init() {
Person.setPersonRepository(personRepository);
}
}
回答3:
As these answers are old, this is one I liked and is very clean that works with just java annotations:
To fix it, create a “none static setter” to assign the injected value for the static variable. For example :
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class GlobalValue {
public static String DATABASE;
@Value("${mongodb.db}")
public void setDatabase(String db) {
DATABASE = db;
}
}
https://www.mkyong.com/spring/spring-inject-a-value-into-static-variables/
来源:https://stackoverflow.com/questions/11324372/how-to-make-spring-inject-value-into-a-static-field