programing

스프링 @자동 배선 속성 대 세터

javajsp 2023. 8. 7. 22:20

스프링 @자동 배선 속성 대 세터

속성에 대한 주석 @Autowired 또는 세터에서 수행하는 것의 차이점은 무엇입니까?

제가 알기로는 둘 다 같은 결과를 가지고 있는 것으로 알고 있는데, 둘 중에 하나를 사용해야 할 이유가 있나요?

UPDATE(간단히 말하면)

이것과 다른 점이 있습니까?

package com.tutorialspoint;

import org.springframework.beans.factory.annotation.Autowired;

public class TextEditor {
   private SpellChecker spellChecker;

   @Autowired
   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }

   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

그리고 이것

package com.tutorialspoint;

import org.springframework.beans.factory.annotation.Autowired;

public class TextEditor {
   @Autowired
   private SpellChecker spellChecker;

   public TextEditor() {
      System.out.println("Inside TextEditor constructor." );
   }

   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

때때로 클래스 A의 인스턴스가 필요하지만 클래스의 필드에 A를 저장하지 않습니다.
원샷 작업을 수행하려면 A 인스턴스만 있으면 됩니다.또는 A 인스턴스(instance)를 사용하여 B 인스턴스(instance)를 얻고 필드에 B를 저장합니다.

이러한 경우에는 세터(또는 생성자) 오토와이어가 더 적합합니다.
사용되지 않는 클래스 수준 필드는 없습니다.

구체적인 예:
RabbitTemplate(RabbitMQ로 메시지를 보내는 개체)를 구성해야 합니다. 구성하려면 ConnectionFactory가 필요합니다.
http://docs.spring.io/spring-amqp/docs/latest_ga/api/org/springframework/amqp/rabbit/core/RabbitTemplate.html#RabbitTemplate-org.springframework.amqp.rabbit.connection.ConnectionFactory-http ://docs.spring.io/spring-amqp/docs/latest_ga/api/org/springframework/amqp/rabbit/core/RabbitTemplate.html#RabbitTemplate-org.springframework.amqp.rabbit.connection.ConnectionFactory-

해당 Connection Factory를 저장할 필요가 없습니다.이 경우 다음과 같은 코드가 표시됩니다.

Class MyClass {
private RabbitTemplate template;

@Autowired 
void setConnectionFactory(ConnectionFactory c) {
    template=new RabbitTemplate(c);
}
}

...연결 공장 필드를 직접 자동 배선하는 것보다 더 나은 서비스를 제공합니다.

이 예에서는 개체가 항상 완전히 생성되므로 생성자 수준에서 자동 배선이 훨씬 더 좋습니다.Connection Factory는 선택적 종속성이 아닌 필수 종속성임이 분명합니다.

와 함께@Autowired주석, 세터 방법이 필요하지 않습니다.빈의 생성자가 개체 할당/생성을 완료하면 Spring이 이 주석을 스캔하여 주석을 추가한 개체 인스턴스를 주입합니다.

setter가 있고 xml 구성을 사용 중인 경우 속성을 명시적으로 설정합니다.

그렇긴 하지만, 당신은 자동 배선 주석으로 당신의 생성자와 세터 방법에 주석을 달 수 있는데, 이것은 나중에 내가 스프링에서 벗어날 수 있는 유연성을 줄 것이기 때문에 나는 선호합니다(하지만 나는 그렇게 하지 않을 것입니다.

사용하는 경우@Autowired속성 대한 주석, spring.xml을 사용하여 속성을 시작합니다.이 경우에는 세터가 필요 없습니다.

사용하는 경우@Autowired세터 주석, 이 속성으로 다른 속성을 초기화하는 것과 같이 사용자 지정 코드를 추가할 수 있는 이 세터 메서드를 사용하여 이 속성을 시작해야 한다고 봄에 지정합니다.

예를 들어 사용:JdbcTemplate를 사용하여 DAO 작업을 사용하는 경우 JdbcTemplate에 대한 입력으로 DataSource가 필요하지만 DataSource 자체가 속성으로 필요하지는 않습니다.따라서 데이터 소스 설정기를 사용하여 데이터 소스 설정기를 자동 배선하여 JdbcTempate를 초기화할 수 있습니다.아래 코드를 참조하십시오.

class DaoDemo{
   //@Autowired
   //private DataSource dataSource;
   private JdbcTemplate jdbcTemplate;

   @Autowired
   public void setDataSource(DataSource dataSource){
     //this.dataSource = dataSource;  
     this.jdbcTemplate = new JdbcTemplate(dataSource);
   }

   public int getTableRowCount(){
      String sql = "SELECT COUNT(*) FROM DEMOTABLE";
      //jdbcTemplate.setDataSource(dataSource);    //No need to do this as its done in DataSource Setter now.
      return jdbcTemplate.queryForObject(sql,Integer.class);

}

위의 코드에서 dataSource의 유일한 사용은 JdbcTemplate에서 전달되는 것이었습니다.따라서 dataSource 속성을 만드는 것은 여기서 의미가 없습니다.따라서 DataSource bean의 @Autowired on setter 메서드를 사용하여 spring.xml에서 항목을 가져와 특정 시간에 사용합니다.

자동 배선에는 세 가지 유형이 있습니다.

  • 자산 기반
@Autowired
private MyService service;
  • 생성자 기반.에서는 Spring Boot도.@Autowired 경우 주석:
class MyController {
 private final MyService service;

 public MyController(MyService service) {
  this.service = service;
 }
}
  • 설정자 기반:
private MyService service;


@Autowired
public void setService(MyService service) {
 this.service = service;
}

생성자 기반을 사용하고, 가능하지 않을 경우 세터 기반과 마지막으로 특성 기반을 사용하는 것이 좋습니다.

왜요?

  • 첫째, 생성자 기반에서는 스프링 주석을 사용하지 않기 때문입니다.이를 통해 다른 프레임워크로 전환할 수 있습니다.

  • 둘째, 컨스트럭터 또는 세터 기반으로 유닛 테스트를 훨씬 쉽게 할 수 있습니다.Spring 전용 테스트 도구를 사용할 필요가 없으며 Junit 및 Mockito만 사용할 수 있습니다.

  • 을 셋째, 생자기속다성같음으로 선언할 수 있기 .final그리고 수업의 불변성과 스레드 안전에 도움이 되는 세터를 노출하지 않습니다.

자동 배선은 프로젝트 전체에서 일관되게 사용될 때 가장 잘 작동합니다.자동 배선이 일반적으로 사용되지 않는 경우 개발자가 자동 배선을 사용하여 하나 또는 두 개의 빈 정의만 배선하는 것이 혼란스러울 수 있습니다.필드에 @Autowired를 사용하면 세터 방법이 필요하지 않습니다. 이것은 한편으로는 클래스를 더 작고 읽기 쉽게 만들지만 다른 한편으로는 클래스를 조롱하는 것을 더 나쁘게 만듭니다.

속성 및 생성자 인수 설정의 명시적 종속성은 항상 자동 배선을 재정의합니다.원시, 문자열 및 클래스(및 이러한 단순 속성 배열)와 같은 소위 단순 속성은 자동 배선할 수 없습니다.이 제한 사항은 설계에 따라 결정됩니다.

자동 배선은 명시적 배선보다 정확하지 않습니다.Spring은 예상치 못한 결과를 초래할 수 있는 모호성의 경우 추측하지 않도록 주의하며, Spring 관리 개체 간의 관계는 더 이상 명시적으로 문서화되지 않습니다.

스프링 컨테이너에서 설명서를 생성할 수 있는 공구에서는 배선 정보를 사용할 수 없습니다.

컨테이너 내의 다중 빈 정의는 자동 배선될 setter 메서드 또는 생성자 인수에 의해 지정된 유형과 일치할 수 있습니다.배열, 컬렉션 또는 맵의 경우 반드시 문제가 되는 것은 아닙니다.그러나 단일 값을 기대하는 종속성의 경우 이 모호성이 임의로 해결되지 않습니다.고유한 빈 정의를 사용할 수 없는 경우 예외가 발생합니다.

할 수 있다면 세터는 피해야 합니다.필요없으면 없는 게 낫지 않나요?

저는 개인적으로 제가 글을 쓸 수 있게 해주는 Guice를 선호합니다.

public class TextEditor {
   private final SpellChecker spellChecker;

   @Inject public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

이것은 한 단계 더 나아갑니다.와 함께final필드, 나는 그것이 절대 변하지 않을 것을 알고 있고 멀티스레딩 가시성 보장을 받습니다.

선택적 속성에서 @Autowired를 사용할 수 없는 경우가 있습니다.

해당 속성을 사용하여 초기화를 수행하려는 경우 생성자를 호출하기 전에 초기화가 설정되지 않을 수 있으며, 선택 사항이므로 생성자에 인수로 넣을 수 없습니다.

이 경우 속성이 자동 배선된 후 초기화를 수행할 수 있도록 @Autowired setter 메서드를 사용하는 것이 좋습니다.

언급URL : https://stackoverflow.com/questions/33562731/spring-autowire-property-vs-setter