我有一个带有静态方法的 Util 类。在我的 Util 类中,我想使用 spring beans,因此我将它们包含在我的 util 类中。 据我所知,使用 spring bean 作为静态字段并不是一个好的做法。 但是有没有办法以静态方法访问spring bean呢?
我的例子:
public class TestUtils {
private static TestBean testBean;
public void setTestBean(TestBean testBean) {
TestUtils.testBean = testBean;
}
public static String getBeanDetails() {
return beanName = testBean.getDetails();
}
}
我在很多论坛上都看到这不是最佳实践。有人可以告诉我如何处理这种情况吗?
我的配置文件:
<bean id="testUtils" class="com.test.TestUtils">
<property name="testBean" ref="testBean" />
</bean>
我的方法是对于希望访问的 bean 来实现
InitializingBean
或使用 @PostConstruct
,并包含对其自身的静态引用。
例如:
@Service
public class MyBean implements InitializingBean {
private static MyBean instance;
@Override
public void afterPropertiesSet() throws Exception {
instance = this;
}
public static MyBean get() {
return instance;
}
}
因此,在静态类中的用法将是:
MyBean myBean = MyBean.get();
这样,不需要 XML 配置,不需要将 bean 作为构造函数参数传递,并且调用者不需要知道或关心 bean 是使用 Spring 连接的(即不需要混乱的
ApplicationContext
变量)。
静态方法的结果应该仅取决于传递到方法中的参数,因此不需要调用任何bean。
如果您需要调用另一个 bean,那么您的方法应该是独立 bean 的成员方法。
其他答案为您提供了可行的解决方案,但事实上可以完成并不意味着应该这样做。
您还可以实现 ApplicationContextAware 接口,如下所示:
@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) {
TestUtils.ac = ac;
}
}
这对我有用。
使用 xml 配置定义您的 bean(老派):
<bean id="someBean1" 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>
或者用java而不是xml定义它(new school)
@Bean(name = "someBean2")
public MySpringComponent loadSomeSpringComponent() {
MySpringComponent bean = new MySpringComponent();
bean.setSomeProperty("1.0.2");
return bean;
}
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
public class TestUtils {
public static void getBeansFromSpringContext() {
WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
//for spring boot apps
//ApplicationContext context = SpringApplication.run(Application.class, args)
DataSource datasource = (DataSource)context.getBean("someBean1");
MySpringComponent springBean = (MySpringComponent)context.getBean("someBean2");
}
}
与问题无关,但如果有人需要访问特定的bean而没有推荐的
@Autowired
,你可以使用这个:
@Autowired
private ApplicationContext appContext;
LdapConnector ldapConnector = (LdapConnector) appContext.getBean("myFooBean");
在入口点
@Bean(name = "myFooBean")
public LdapConnector myFooBeanInit() throws Exception {
LdapConnector ldapFooConnector = new LdapConnectorImpl();
ldapAcademicConnector.enableVerboseLog();
ldapAcademicConnector.addCertToTrueStore();
ldapAcademicConnector.disableSanMatch();
与@nullPainter的响应类似,但我们做了以下操作。不需要构建后逻辑。它只是在注入期间直接设置静态成员(在 @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;
}
}
这就是我从 spring 注入静态字段的方式。
<bean id="..." class="...">
<property name="fieldToBeInjected">
<util:constant static-field="CONSTANT_FIELD" />
</property>
</bean>
也许这也会对你有帮助。
您概述的方法是我所看到的用于将 Spring bean 注入实用程序类的方法。
<bean id="testUtils" class="com.test.TestUtils">
<property name="testBean" ref="testBean" />
</bean>
另一个选项是:
<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>
与:
public class TestUtils {
private static testBean;
public static void setInstance(TestBean anInstance) {
testBean = anInstance;
}
public static String getBeanDetails() {
return testBean.getDetails();
}
}
您可以将所有相关的东西组合到一个地方:
@Configuration
public class TestConfiguration {
private static TestBean testBean;
@Bean
public void testBean() {
TestBean tb = new TestBean();
testBean = tb;
return tb;
}
public static String getBeanDetails() {
return testBean.getDetails();
}
}