Java 您可以将@Autowired与静态字段一起使用吗?
是否有方法将Java 您可以将@Autowired与静态字段一起使用吗?,java,spring,autowired,Java,Spring,Autowired,是否有方法将@Autowired与静态字段一起使用。如果没有,还有其他方法吗?简而言之,没有。您不能在Spring中自动关联或手动关联静态字段。为此,您必须编写自己的逻辑。创建一个bean,您可以自动连接该bean,将静态变量初始化为副作用 @Autowired可以与setter一起使用,这样就可以让setter修改静态字段 最后一个建议不要您可以使用XML表示法和方法调用FactoryBean来实现这一点。例如,请看 您应该尽可能使用spring注入,因为这是推荐的方法,但这并不总是可能的,因
@Autowired
与静态字段一起使用。如果没有,还有其他方法吗?简而言之,没有。您不能在Spring中自动关联或手动关联静态字段。为此,您必须编写自己的逻辑。创建一个bean,您可以自动连接该bean,将静态变量初始化为副作用 @Autowired
可以与setter一起使用,这样就可以让setter修改静态字段
最后一个建议不要您可以使用XML表示法和
方法调用FactoryBean
来实现这一点。例如,请看
您应该尽可能使用spring注入,因为这是推荐的方法,但这并不总是可能的,因为我相信您可以想象,并非所有内容都可以从spring容器中提取,或者您可能正在处理遗留系统
注意:使用这种方法进行测试也可能更困难。在@PostConstruct方法中初始化自动连接组件
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
@Component
public class TestClass {
private static AutowiredTypeComponent component;
@Autowired
private AutowiredTypeComponent autowiredComponent;
@PostConstruct
private void init() {
component = this.autowiredComponent;
}
public static void testMethod() {
component.callTestMethod();
}
}
您可以使用ApplicationContextAware
@组件
公共类AppContext实现ApplicationContextAware{
公共静态应用程序上下文应用程序上下文;
公共AppBeans(){
}
@凌驾
public void setApplicationContext(ApplicationContext ApplicationContext)抛出BeansException{
this.applicationContext=applicationContext;
}
}
然后
免责声明这绝不是标准,spring很可能有更好的方法来做到这一点。上述答案均未解决公共静电场布线问题 我想完成三件事
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
我们已经检查了1和2,现在我们如何防止调用setter,因为我们无法隐藏它
@Component
@Aspect
public class FinalAutowiredHelper {
@Before("finalMethods()")
public void beforeFinal(JoinPoint joinPoint) {
throw new FinalAutowiredHelper().new ModifySudoFinalError("");
}
@Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")
public void finalMethods() {}
public class ModifySudoFinalError extends Error {
private String msg;
public ModifySudoFinalError(String msg) {
this.msg = msg;
}
@Override
public String getMessage() {
return "Attempted modification of a final property: " + msg;
}
}
此方面将包装以final开头的所有方法,并在调用它们时抛出错误
我不认为这是特别有用的,但如果你是强迫症,想让你的豌豆和胡萝卜分开,这是一种安全的方法
重要Spring在调用函数时不会调用方面。更简单的是,糟糕的是,我在弄清楚之前已经计算出了逻辑。想要添加到答案中,自动布线静态场(或常量)将被忽略,但也不会产生任何错误:
@Autowired
private static String staticField = "staticValue";
通常,按对象实例设置静态字段是一种不好的做法 为了避免可选问题,您可以添加
synchronized
定义,并仅在专用静态记录器的情况下设置它
@Autowired
public synchronized void setLogger(Logger logger)
{
if (MyClass.logger == null)
{
MyClass.logger = logger;
}
}
:你为什么不建议这样做?嗯。。我对为什么不推荐它的感觉是,因为类中的静态实例超出了spring的控制范围。一旦注入,静态字段就是对应(周围)类的所有对象实例的引用。但是,这种行为可能正是预期的结果,因此可能被视为一个bug或一个功能…是的@matthaeus,这正是我在需要访问org.springframework.core.env.env.Environment时所期望的功能:
@Component public class SpringAppEnv{public static Environment_env;@Autowired public void setEnv(环境环境){u env=env;}
@JonLorusso等等,因为当类加载器加载静态值时,还不需要加载Spring上下文。因此,类加载器将无法在bean中正确注入静态类,并且将失败。Andrea Two提供的答案当你发现旧代码在这样做时,这是一种反模式。眯着眼睛,歪着头,找到更好的方法来解决问题。你会很高兴你这么做。这对Spring的@AutoWired
也很有帮助。你知道我在初始化存储库时如何使用这种方法吗?缺点:没有保证如果以静态方式访问,hatsomeThing
已被初始化:NewClass.staticMethodWhichUsesSomething();
如果在应用程序初始化之前使用,可能会引发NPE。您是否可以避免出现实例方法不应写入“静态”字段的警告(squid:S2696)
?@user7294900:仅在这种非常特殊的情况下禁用此警告。@如果我在广泛的情况下选择此解决方案,izogfif仍然是一个问题。您可以避免出现实例方法不应写入“静态”字段的警告(squid:S2696)
?您也可以直接通过构造函数执行此操作。@user7294900我想这个警告告诉我们为什么这被视为反模式。当实例方法写入静态变量时,静态变量成为类的所有对象之间共享的关键资源,从而在多线程应用程序中产生潜在问题环境。这节省了我的时间。虽然这段代码可能会解决问题,但它如何以及为什么会真正有助于提高您的文章质量,并可能导致更多的投票。请记住,您是在将来为读者回答问题,而不仅仅是现在提问的人。请您的答案添加解释和说明给出适用的限制和假设。我认为这个答案可能根本不需要任何解释。相关
@Component
@Aspect
public class FinalAutowiredHelper {
@Before("finalMethods()")
public void beforeFinal(JoinPoint joinPoint) {
throw new FinalAutowiredHelper().new ModifySudoFinalError("");
}
@Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")
public void finalMethods() {}
public class ModifySudoFinalError extends Error {
private String msg;
public ModifySudoFinalError(String msg) {
this.msg = msg;
}
@Override
public String getMessage() {
return "Attempted modification of a final property: " + msg;
}
}
@Autowired
private static String staticField = "staticValue";
@Autowired
public synchronized void setLogger(Logger logger)
{
if (MyClass.logger == null)
{
MyClass.logger = logger;
}
}