그리고 정적Autowired 법 @
있습니다@Autowired
정적 방식 내에서 사용해야 하는 서비스입니다.잘못된 것은 알지만 많은 작업이 필요하기 때문에 현재 디자인을 변경할 수 없기 때문에 간단한 해커가 필요합니다.나는 바꿀 수 없다randomMethod()
정전기 방지용 콩을 사용해야 합니다.어떻게 하는지 단서가 있나요?
@Service
public class Foo {
public int doStuff() {
return 1;
}
}
public class Boo {
@Autowired
Foo foo;
public static void randomMethod() {
foo.doStuff();
}
}
하나를 해결책에 따라:이 할 수 있다.
Autowired @를 사용하여 생성자
이 접근법은 콩 생성자 매개 변수로 콩을 요구하게 된다.생성자 코드 이내에 당신은 값을 생성자 실행에 대한 매개 변수로 받고 정적 필드를 세웠다.샘플:
@Component
public class Boo {
private static Foo foo;
@Autowired
public Boo(Foo foo) {
Boo.foo = foo;
}
public static void randomMethod() {
foo.doStuff();
}
}
PostConstruct @ 정적 필드에 손에 사용됩니다.
여기서의 생각은 후에 콩 스프링으로 구성된 정적 필드에 콩을 양도하는 것이다.
@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();
}
}
정전기 응용 컨텍스트accessor 접근법을 통해 이 workaround에 갖게 된다.
@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);
}
}
그리고는 정적 방식으로 콩 인스턴스에 액세스 할 수 있다.
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();
}
}
콩이 가공되면, 스프링이 주사할 것입니다.Foo
인스턴스 필드에 구현 인스턴스foo
그런 다음 같은 것을 주입합니다.Foo
에 인스턴스하다.setStaticFoo()
static 필드를 설정하기 위해 사용됩니다.
이는 끔찍한 회피책이며, 이 방법을 사용하려고 하면 실패합니다.randomMethod()
봄이 지나기 전에Boo
.
스태틱 콘텍스트를 작성하는 가장 쉬운 방법은 응용 프로그램을 시작할 때 자연스럽게 작성하는 것입니다.이것에 의해, 추가 클래스의 부자연스러운 실장이 불필요하게 되는 것을 막을 수 있습니다.
@SpringBootApplication
public class MyApplication {
private static ApplicationContext appContext;
public static void main(String[] args) {
appContext = SpringApplication.run(MyApplication.class, args);
}
public static ApplicationContext getAppContext() {
return appContext;
}
}
그런 다음 Bean에 정적으로 액세스해야 하는 모든 위치에서 ApplicationContext를 사용하여 클래스의 인스턴스를 가져올 수 있습니다.
public class Boo {
public static void randomMethod() {
MyApplication.getAppContext()
.getBean(Foo.class).doStuff();
}
}
잘 부탁드립니다.
구린내 나는데 콩을 구하려면ApplicationContextAware
인터페이스입니다.예를 들어 다음과 같습니다.
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;
}
}
이는 정적 getBean 메서드에서 액세스할 때 스프링 컨텍스트가 초기화되지 않을 가능성을 해결하기 위해 @Pavel의 답변을 기반으로 합니다.
@Component
public class Spring {
private static final Logger LOG = LoggerFactory.getLogger (Spring.class);
private static Spring spring;
@Autowired
private ApplicationContext context;
@PostConstruct
public void registerInstance () {
spring = this;
}
private Spring (ApplicationContext context) {
this.context = context;
}
private static synchronized void initContext () {
if (spring == null) {
LOG.info ("Initializing Spring Context...");
ApplicationContext context = new AnnotationConfigApplicationContext (io.zeniq.spring.BaseConfig.class);
spring = new Spring (context);
}
}
public static <T> T getBean(String name, Class<T> className) throws BeansException {
initContext();
return spring.context.getBean(name, className);
}
public static <T> T getBean(Class<T> className) throws BeansException {
initContext();
return spring.context.getBean(className);
}
public static AutowireCapableBeanFactory getBeanFactory() throws IllegalStateException {
initContext();
return spring.context.getAutowireCapableBeanFactory ();
}
}
여기서 중요한 건initContext
방법.그러면 컨텍스트가 항상 초기화됩니다.단, 주의해 주십시오.initContext
동기화할 때 코드의 경합 포인트가 됩니다.애플리케이션이 고도로 병렬화되어 있는 경우(예를 들어 트래픽이 많은 사이트의 백엔드)에는 이 솔루션이 적합하지 않을 수 있습니다.
AppContext를 사용합니다.컨텍스트 파일에 빈을 작성해야 합니다.
private final static Foo foo = AppContext.getApplicationContext().getBean(Foo.class);
public static void randomMethod() {
foo.doStuff();
}
언급URL : https://stackoverflow.com/questions/17659875/autowired-and-static-method
'programing' 카테고리의 다른 글
Java(UUID.random)에서 UUID 문자열을 생성하는 효율적인 방법대시 없음 UUID().toString() (0) | 2022.09.05 |
---|---|
치명적인 예외: Firebase-Messaging-Intent-Handle --java.lang.NoClassDefFoundError(NoClassDefFound 오류) (0) | 2022.09.05 |
한계와 반대되는 MariaDB (0) | 2022.09.05 |
mysql: 인식할 수 없는 서비스 (0) | 2022.09.05 |
Vue + vuex 개체 돌연변이 (0) | 2022.09.05 |