Spring에서 자체 인스턴스화 된 객체에 종속성을 주입하는 방법은 무엇입니까?


128

수업이 있다고 가정 해 봅시다.

public class MyClass {
    @Autowired private AnotherBean anotherBean;
}

그런 다음이 클래스의 객체를 만들었습니다 (또는 다른 프레임 워크에서이 클래스의 인스턴스를 만들었습니다).

MyClass obj = new MyClass();

여전히 의존성을 주입 할 수 있습니까? 다음과 같은 것 :

applicationContext.injectDependencies(obj);

(Google Guice에는 이와 같은 것이 있다고 생각합니다)

답변:


194

autowireBean()방법을 사용하여이 작업을 수행 할 수 있습니다 AutowireCapableBeanFactory. 당신은 임의의 객체를 전달하고 Spring은 그것을 스스로 만든 것처럼 취급하고 다양한 자동 배선 비트와 조각을 적용합니다.

의 정보를 얻으려면 AutowireCapableBeanFactory다음을 자동 연결하십시오.

private @Autowired AutowireCapableBeanFactory beanFactory;

public void doStuff() {
   MyBean obj = new MyBean();
   beanFactory.autowireBean(obj);
   // obj will now have its dependencies autowired.
}

좋은 답변입니다 (+1). autowiring이 발생하는 방식에 영향을 줄 수있는 두 번째 방법도 있습니다. static.springsource.org/spring/docs/3.0.x/javadoc-api/org/…
Sean Patrick Floyd

그러나 두 개의 객체가 있고 먼저 자동 와이어를 사용하면 어떻게 될까요? autowire bean factory는이 경우 종속성을 어떻게 처리합니까?
Vadim Kirilchuk

3
이것은 실제로 나쁜 패턴입니다. 이것이 실제로 MyBean을 사용하는 방법이라면 AnotherBean을 매개 변수로 사용하는 생성자를 사용하지 않는 이유는 무엇입니까? 같은 뭔가 : code개인 @Autowired AnotherBean 콩; 공공 무효 doStuff () {MyBean obj = 새로운 MyBean (bean); } code. 이 모든 주석과 같이 사람들이 실제로 혼란스러워하고 1 일 이후 Java SDK에 있었던 기본 패턴을 사용하지 않는 것 같습니다. :(
Denis

3
동의합니다-Spring은 전체 언어를 재정의했습니다. 이제 우리는 인터페이스를 구체적인 클래스로 사용하고, 클래스 인스턴스로 메소드를 사용하며, 새롭고 알맞은 디자인으로 수행했던 작업을 수행하는 복잡하고 코드가 많은 모든 방법을 사용합니다.
Rodney P. Barbati

@Denis MyBean에 실제 클래스에 필요하지 않은 종속성이있는 경우 실제로 존재하지 않는 종속성을 클래스를 인스턴스로 등록하기 때문에 실제로 차이가 없습니다.
Dalton

17

@Configurable 주석으로 MyClass를 표시 할 수도 있습니다.

@Configurable
public class MyClass {
   @Autowired private AnotherClass instance
}

그런 다음 생성시 종속성을 자동으로 주입합니다. 또한 <context:spring-configured/>응용 프로그램 컨텍스트 xml에 있어야합니다 .


2
Galz666, 당신의 방법은 내가하고 싶은 일에 대해 훨씬 깨끗해 보입니다. 그러나 나는 그것을 작동시킬 수 없다. xml 파일이 없으며 전적으로 Java 구성을 사용하고 있습니다. 에 해당 <context:spring-configured/>하는가?
masstroy

1
이것은 깨끗한 솔루션이지만 약간의 노력이 더 필요합니다. 위의 iimuhin과 같이로드 타임 직조를 사용하거나 AspectJ 컴파일러를 프로젝트에 추가해야합니다. 이름에서 알 수 있듯이로드 타임은 런타임에 추가 비용을 발생시킵니다.
jsosnowski

4

방금 같은 요구가 있었고 내 경우에는 이미 Spring이 관리 할 수없는 Java 클래스의 논리에 액세스했습니다 ApplicationContext. 스카프 맨에서 영감을 얻었습니다. 해결 방법 :

AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean(manuallyCreatedInstance);

3

나는 다음 내 솔루션 공유하기를 원해요 @Configurable으로 접근을 brieflyglaz666 @에서 언급 한 대답 때문에를

  • @skaffman 의 답변 은 거의 10 살이며 충분하지 않거나 작동하지 않는다는 의미는 아닙니다.
  • @ glaz666의 대답은 간단하고 실제로 문제를 해결하는 데 도움이되지는 않았지만 올바른 방향으로 나를 가리 켰습니다.

내 설정

  1. Spring Boot 2.0.3 with Spring Neo4j & Aop starts(어쨌든 관련이 없음)
  2. 접근 방식을 사용하여 Spring Boot준비가 되면 Bean을 인스턴스화하십시오 @Configurable( ApplicationRunner)
  3. 그레들 & 이클립스

단계

작동하려면 아래 단계를 따라야했습니다.

  1. @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = false)당신의 상단에 배치하는 Bean수동으로 인스턴스화하는 것입니다. 내 경우에는 Bean수동으로 인스턴스화 해야하는 @Autowired서비스가 있으므로 위의 주석에 소품이 있습니다.
  2. 봄 부팅의 주요 주석 XXXApplicaiton.java(주석 또는 파일을 @SpringBootApplication사용) @EnableSpringConfigured@EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
  3. (즉, build.gradle 또는의 pom.xml하는 일에 사용 따라) 빌드 파일의 종속성을 추가 compile('org.springframework.boot:spring-boot-starter-aop')하고compile('org.springframework:spring-aspects:5.0.7.RELEASE')
  4. 어디서나 Bean주석이 달린 새로운 기능 + @Configurable의존성이 자동 배선되어야합니다.

* 위의 3 번 지점과 관련하여 필자는 org.springframework.boot:spring-boot-starter-aop전 이적으로 spring-aop(여기에 표시된 것처럼 mavencentral )를 가져 오는 것을 알고 있지만 Eclipse의 경우 @EnableSpringConfigured주석 을 해결하지 못했기 때문에 spring-aop스타터 외에도 종속성을 명시 적으로 추가 한 이유는 무엇입니까? 같은 문제에 직면하면 의존성을 선언하거나 알아내는 모험을 떠나십시오.

  • 버전 충돌이 있습니까
  • org.springframework.context.annotation.aspect.*사용할 수없는 이유
  • IDE 설정이 올바르게되어 있습니까
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.