스프링 @자동 배선 속성 대 세터
속성에 대한 주석 @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
'programing' 카테고리의 다른 글
jQuery UI 정렬 가능 위치 (0) | 2023.08.07 |
---|---|
ADO.NET을 사용하여 테이블 값 매개 변수 전달 (0) | 2023.08.07 |
pkl 파일의 압축을 푸는 방법은? (0) | 2023.08.07 |
대체 패턴에서 그룹 캡처에 대한 역참조 처리 (0) | 2023.08.07 |
HTML에서 세로줄을 만드는 방법 (0) | 2023.08.07 |