你可以将@Autowired与静态字段一起使用吗?

时间:2009-06-19 16:11:23

标签: java spring

是否有某种方法可以将@Autowired与静态字段一起使用。如果没有,还有其他方法吗?

11 个答案:

答案 0 :(得分:100)

简而言之,没有。您无法在Spring中自动装配或手动连​​接静态字段。你必须编写自己的逻辑才能做到这一点。

答案 1 :(得分:89)

@Component("NewClass")
public class NewClass{
    private static SomeThing someThing;

    @Autowired
    public void setSomeThing(SomeThing someThing){
        NewClass.someThing = someThing;
    }
}

答案 2 :(得分:63)

@Autowired可与setter一起使用,因此您可以让setter修改静态字段。

只有一个最终建议...... 不要

答案 3 :(得分:7)

在@PostConstruct方法

中初始化自动装配的组件
@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();
   }
}

答案 4 :(得分:5)

创建一个可以自动装配的bean,它将静态变量初始化为副作用。

答案 5 :(得分:4)

您可以使用 XML表示法MethodInvokingFactoryBean来实现此目的。例如,here

private static StaticBean staticBean;

public void setStaticBean(StaticBean staticBean) {
   StaticBean.staticBean = staticBean;
}

你应该尽可能使用弹簧注射,因为这是推荐的方法,但这并不总是可行的,因为我相信你可以想象不是所有东西都可以从弹簧容器或你可能正在处理遗留系统。

注意使用这种方法测试也会更加困难。

答案 6 :(得分:0)

您可以使用ApplicationContextAware

@Component
public class AppContext implements ApplicationContextAware{
    public static ApplicationContext applicationContext;

    public AppBeans(){
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

然后

static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);

答案 7 :(得分:0)

免责声明这绝不是标准的,并且很可能会有更好的春季方法。以上答案均未解决连接公共静态字段的问题。

我想完成三件事。

  1. 使用spring来“自动装配”(我使用@Value)
  2. 公开公共静态值
  3. 防止修改

我的对象看起来像这样

private static String BRANCH = "testBranch";

@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
    BRANCH = branch;
}

public static String BRANCH() {
    return BRANCH;
}

我们现在已经检查了1和2,因为我们无法隐藏它,所以我们如何防止对其调用。

@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结尾的方法,如果调用它们,则会抛出错误。

我认为这不是特别有用,但是如果您是ocd,并且喜欢将豌豆和胡萝卜分开,则这是一种安全的方法。

重要 Spring在调用函数时不会调用您的方面。使这变得更容易,更糟糕的是我在弄清楚之前弄清楚了逻辑。

答案 8 :(得分:0)

想要添加到答案中,自动布线的静态字段(或常数)将被忽略,但也不会产生任何错误:

ZonedDateTime

答案 9 :(得分:0)

通常,按对象实例设置静态字段是一种不好的做法。

为避免出现可选问题,您可以添加synchronized定义,并仅在使用私有静态Logger记录器时进行设置;

@Autowired
public synchronized void setLogger(Logger logger)
{
    if (MyClass.logger == null)
    {
        MyClass.logger = logger;
    }
}

答案 10 :(得分:-1)

make