programing

독립 실행형 Java 응용 프로그램에서 Spring 3 자동 배선 사용

lastmoon 2023. 7. 31. 21:47
반응형

독립 실행형 Java 응용 프로그램에서 Spring 3 자동 배선 사용

내 코드는 다음과 같습니다.

public class Main {

    public static void main(String[] args) {
        Main p = new Main();
        p.start(args);
    }

    @Autowired
    private MyBean myBean;
    private void start(String[] args) {
        ApplicationContext context = 
            new ClassPathXmlApplicationContext("META-INF/config.xml");
        System.out.println("my beans method: " + myBean.getStr());
    }
}

@Service 
public class MyBean {
    public String getStr() {
        return "string";
    }
}

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 
    <context:annotation-config /> 
    <context:component-scan base-package="mypackage"/>
</beans>

왜 안 되는 거지?알겠습니다NullPointerException독립 실행형 응용 프로그램에서 자동 배선을 사용할 수 있습니까?

스프링은 독립 실행형 애플리케이션에서 작동합니다.당신은 봄콩을 만들기 위해 잘못된 방법을 사용하고 있습니다.올바른 방법은 다음과 같습니다.

@Component
public class Main {

    public static void main(String[] args) {
        ApplicationContext context = 
            new ClassPathXmlApplicationContext("META-INF/config.xml");

        Main p = context.getBean(Main.class);
        p.start(args);
    }

    @Autowired
    private MyBean myBean;
    private void start(String[] args) {
        System.out.println("my beans method: " + myBean.getStr());
    }
}

@Service 
public class MyBean {
    public String getStr() {
        return "string";
    }
}

첫 번째 경우(문제의 경우)에서는 개체를 Spring 컨텍스트에서 가져오는 것이 아니라 개체를 직접 만드는 것입니다.그래서 Spring은 기회를 얻지 못합니다.Autowire종속성(이로 인해 발생함)NullPointerException).

두 번째 경우(이 답변의 경우)에서는 봄 맥락에서 콩을 얻으므로 봄이 관리되고 봄이 관리됩니다.autowiring.

Spring은 XML 파일에서 멀어지고 주석을 많이 사용합니다.다음 예제는 XML 파일 대신 주석을 사용하는 단순한 독립 실행형 Spring 응용 프로그램입니다.

package com.zetcode.bean;

import org.springframework.stereotype.Component;

@Component
public class Message {

   private String message = "Hello there!";

   public void setMessage(String message){

      this.message  = message;
   }

   public String getMessage(){

      return message;
   }
}

이것은 간단한 콩입니다.그것은 그것으로 장식되어 있습니다.@ComponentSpring 컨테이너에 의한 자동 감지를 위한 주석.

package com.zetcode.main;

import com.zetcode.bean.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = "com.zetcode")
public class Application {

    public static void main(String[] args) {

        ApplicationContext context
                = new AnnotationConfigApplicationContext(Application.class);

        Application p = context.getBean(Application.class);
        p.start();
    }

    @Autowired
    private Message message;
    private void start() {
        System.out.println("Message: " + message.getMessage());
    }
}

이것이 메인입니다.Application수업. 그.@ComponentScan주석은 구성요소를 검색합니다.@Autowired주석은 콩을 주입합니다.message변수. 변수.AnnotationConfigApplicationContextSpring 응용 프로그램 컨텍스트를 만드는 데 사용됩니다.

독립 실행형 Spring 자습서에서는 XML과 주석을 모두 사용하여 독립 실행형 Spring 응용 프로그램을 만드는 방법을 참조하십시오.

Spring 4의 경우, ApplicationContext에서 Bean을 직접 가져오는 안티 패턴을 사용하지 않고 Spring Boot을 사용하면 다음과 같은 예를 얻을 수 있습니다.

package com.yourproject;

@SpringBootApplication
public class TestBed implements CommandLineRunner {

    private MyService myService;

    @Autowired
    public TestBed(MyService myService){
        this.myService = myService;
    }

    public static void main(String... args) {
        SpringApplication.run(TestBed.class, args);
    }

    @Override
    public void run(String... strings) throws Exception {
        System.out.println("myService: " + MyService );
    }

}

@Service 
public class MyService{
    public String getSomething() {
        return "something";
    }
}

주입된 모든 서비스가 아래에 있는지 확인합니다.com.yourproject또는 하위 패키지.

SpringBoot를 실행 중인 경우:

정적 메인 메서드에서 서비스 중 하나를 자동으로 연결할 수 없는 동일한 문제가 발생했습니다.

SpringApplication.run에 의존하는 경우 아래의 접근 방식을 참조하십시오.

@SpringBootApplication
public class PricingOnlineApplication {

    @Autowired
    OrchestratorService orchestratorService;

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(PricingOnlineApplication.class, args);
        PricingOnlineApplication application = context.getBean(PricingOnlineApplication.class);

        application.start();
    }

    private void start() {
        orchestratorService.performPricingRequest(null);
    }

}

SpringApplication.run이 위에서 설명한 접근 방식과 유사하게 사용할 수 있는 컨텍스트를 반환한다는 것을 알게 되었습니다.거기서부터 위와 정확히 같습니다 ;-)

좋은 해결책은 다음과 같습니다.

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContext implements ApplicationContextAware {

private static ApplicationContext context;

/**
 * Returns the Spring managed bean instance of the given class type if it exists.
 * Returns null otherwise.
 * @param beanClass
 * @return
 */
public static <T extends Object> T getBean(Class<T> beanClass) {
    return context.getBean(beanClass);
}

@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {

    // store ApplicationContext reference to access required beans later on
    SpringContext.context = context;
}
}

그런 다음 다음과 같이 사용할 수 있습니다.

YourClass yourClass = SpringContext.getBean(YourClass.class);

는 다음 웹사이트에서 이 매우 좋은 해결책을 발견했습니다: https://confluence.jaytaala.com/pages/viewpage.action?pageId=18579463 .

언급URL : https://stackoverflow.com/questions/3659720/using-spring-3-autowire-in-a-standalone-java-application

반응형