Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 您可以将@Autowired与静态字段一起使用吗?_Java_Spring_Autowired - Fatal编程技术网

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很可能有更好的方法来做到这一点。上述答案均未解决公共静电场布线问题

我想完成三件事

  • 使用弹簧“自动连线”(Im使用@Value)
  • 公开一个公共静态值
  • 防止修改
  • 我的物体看起来像这样

    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
    也很有帮助。你知道我在初始化存储库时如何使用这种方法吗?缺点:没有保证如果以静态方式访问,hat
    someThing
    已被初始化:
    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;
        }
    }