@Autowired和静态方法
我有@Autowired
服务,必须在静态方法中使用。 我知道这是错误的,但我不能改变目前的devise,因为它需要很多工作,所以我需要一些简单的黑客。 我不能改变randomMethod()
是非静态的,我需要使用这个autowired bean。 任何线索如何做到这一点?
@Service public class Foo { public int doStuff() { return 1; } } public class Boo { @Autowired Foo foo; public static void randomMethod() { foo.doStuff(); } }
您可以通过以下解决scheme之一来执行此操作:
使用构造函数@Autowired
这种方法将构造需要一些bean作为构造参数的bean。 在构造函数代码中,您使用作为构造函数执行参数获取的值来设置静态字段。 样品:
@Component public class Boo { private static Foo foo; @Autowired public Boo(Foo foo) { Boo.foo = foo; } public static void randomMethod() { foo.doStuff(); } }
使用@PostConstruct将值传递给静态字段
这里的想法是在bean被springconfiguration后,将一个bean移交给一个静态字段。
@Component public class Boo { private static Foo foo; @Autowired private Foo tFoo; @PostConstruct public void init() { Boo.foo = tFoo; } public static void randomMethod() { foo.doStuff(); } }
您必须通过静态应用程序上下文访问器方法解决此问题:
@Component public class StaticContextAccessor { private static StaticContextAccessor instance; @Autowired private ApplicationContext applicationContext; @PostConstruct public void registerInstance() { instance = this; } public static <T> T getBean(Class<T> clazz) { return instance.applicationContext.getBean(clazz); } }
然后你可以静态的方式访问bean实例。
public class Boo { public static void randomMethod() { StaticContextAccessor.getBean(Foo.class).doStuff(); } }
你可以做的是@Autowired
setter方法,并设置一个新的静态字段。
public class Boo { @Autowired Foo foo; static Foo staticFoo; @Autowired public void setStaticFoo(Foo foo) { Boo.staticFoo = foo; } public static void randomMethod() { staticFoo.doStuff(); } }
当bean被处理时,Spring会将一个Foo
实现实例注入实例字段foo
。 然后它会将相同的Foo
实例注入到setStaticFoo()
参数列表中,该列表将用于设置静态字段。
这是一个糟糕的解决方法,如果在Spring处理Boo
实例之前尝试使用randomMethod()
,将会失败。
它很糟糕,但你可以通过使用ApplicationContextAware
接口来获得bean。 就像是 :
public class Boo implements ApplicationContextAware { private static ApplicationContext appContext; @Autowired Foo foo; public static void randomMethod() { Foo fooInstance = appContext.getBean(Foo.class); fooInstance.doStuff(); } @Override public void setApplicationContext(ApplicationContext appContext) { Boo.appContext = appContext; } }
使用AppContext。 确保你在上下文文件中创build一个bean。
private final static Foo foo = AppContext.getApplicationContext().getBean(Foo.class); public static void randomMethod() { foo.doStuff(); }