클리닝 코드 - @Autowire를 적용해야 하는 위치는 어디입니까?
간단한 예로 시작하겠습니다.Spring boot 응용 프로그램이 실행 중입니다.CommandLineRunner
초기화 클래스입니다.
// MyCommandLineRunner.java
public class MyCommandLineRunner implements CommandLineRunner {
private final Log logger = LogFactory.getLog(getClass());
@Autowired //IntelliJ Warning
private DataSource ds;
@Override
public void run(String... args) throws Exception {
logger.info("DataSource: " + ds.toString());
}
}
// Application.java
@SpringBootApplication
public class Application {
public static void main(String... args) {
SpringApplication.run(Application.class, args);
}
@Bean
public MyCommandLineRunner schedulerRunner() {
return new MyCommandLineRunner();
}
}
자, 이렇게, 이것은 작동합니다. 모든 것이 좋습니다.그러나 IntelliJ는 다음과 같은 경고를 보고합니다.@Autowired
위치(댓글의 위치를 표시했습니다)
스프링 팀은 다음을 권장합니다.콩에는 항상 생성자 기반 의존성 주입을 사용합니다.필수 종속성에는 항상 어설션을 사용합니다.
이제 이걸 따르면, 저는 생성자 기반의 의존성 주입이 있습니다.
@Autowired
public MyCommandLineRunner(DataSource ds) { ... }
이것은 또한 내가 편집해야 한다는 것을 의미합니다.Application.java
또한, 생성자는 논쟁이 필요하기 때문입니다.인Application.java
만약 제가 세터 주사를 사용하려고 하면, 저는 같은 경고를 받을 것입니다.만약 제가 그것을 다시 고려한다면, 제 생각에, 저는 몇 가지 끔찍한 코드를 가지게 될 것입니다.
// MyCommandLineRunner.java
public class MyCommandLineRunner implements CommandLineRunner {
private final Log logger = LogFactory.getLog(getClass());
private DataSource ds;
@Autowired // Note that this line is practically useless now, since we're getting this value as a parameter from Application.java anyway.
public MyCommandLineRunner(DataSource ds) { this.ds = ds; }
@Override
public void run(String... args) throws Exception {
logger.info("DataSource: " + ds.toString());
}
}
// Application.java
@SpringBootApplication
public class Application {
private DataSource ds;
@Autowired
public Application(DataSource ds) { this.ds = ds; }
public static void main(String... args) {
SpringApplication.run(Application.class, args);
}
@Bean
public MyCommandLineRunner schedulerRunner() {
return new MyCommandLineRunner(ds);
}
}
위의 코드는 동일한 결과를 산출하지만 IntelliJ에서 어떠한 경고도 보고하지 않습니다.헷갈리네요, 첫 번째 코드보다 두 번째 코드가 어떻게 더 좋을까요?제가 잘못된 논리를 따르고 있나요?다른 방식으로 배선해야 합니까?
간단히 말해서, 이것을 하는 올바른 방법은 무엇입니까?
메모 DataSource
이 질문은 자동 배선되는 모든 항목에 적용됩니다.
참고 2 단지 그것을 말하는 것입니다.MyCommandLineRunner.java
DataSource를 자동 배선/초기화해야 하므로 다른 빈 생성자를 사용할 수 없습니다.오류가 보고되고 컴파일되지 않습니다.
개선할 수 있는 몇 가지 방법이 있습니다.
제거할 수 있습니다.
@Autowired
당신의MyCommandLineRunner
당신이 말하는 것처럼@Bean
메소드는 그것의 인스턴스를 구성합니다.주입합니다.DataSource
인수로서 메소드에 직접 포함됩니다.또는 제거
@Autowired
그리고 그것을 제거합니다.@Bean
그리고 따귀를 때립니다.@Component
에 대한 주석MyCommandLineRunner
감지하고 공장 방식을 제거합니다.인라인 사용자
MyCommandLineRunner
마음속에@Bean
람다 방법입니다.
자동 배선 없음MyCommandLineRunner
public class MyCommandLineRunner implements CommandLineRunner {
private final Log logger = LogFactory.getLog(getClass());
private final DataSource ds;
public MyCommandLineRunner(DataSource ds) { this.ds = ds; }
@Override
public void run(String... args) throws Exception {
logger.info("DataSource: " + ds.toString());
}
}
그리고 애플리케이션 클래스.
@SpringBootApplication
public class Application {
public static void main(String... args) {
SpringApplication.run(Application.class, args);
}
@Bean
public MyCommandLineRunner schedulerRunner(DataSource ds) {
return new MyCommandLineRunner(ds);
}
}
의 사용@Component
@Component
public class MyCommandLineRunner implements CommandLineRunner {
private final Log logger = LogFactory.getLog(getClass());
private final DataSource ds;
public MyCommandLineRunner(DataSource ds) { this.ds = ds; }
@Override
public void run(String... args) throws Exception {
logger.info("DataSource: " + ds.toString());
}
}
그리고 애플리케이션 클래스.
@SpringBootApplication
public class Application {
public static void main(String... args) {
SpringApplication.run(Application.class, args);
}
}
인라인CommandLineRunner
@SpringBootApplication
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class)
public static void main(String... args) {
SpringApplication.run(Application.class, args);
}
@Bean
public MyCommandLineRunner schedulerRunner(DataSource ds) {
return (args) -> (logger.info("DataSource: {}", ds);
}
}
이 모든 것은 인스턴스를 구성하는 데 유효한 방법입니다.어떤 것을 사용할지, 당신이 편한 것을 사용하세요.더 많은 옵션(여기에 언급된 옵션에 대한 모든 변형)이 있습니다.
필드를 만드는 것을 고려합니다.ds
최종적으로, 그러면 당신은 필요하지 않습니다.@Autowired
종속성 주입에 대한 자세한 내용은 http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-spring-beans-and-dependency-injection.html#using-boot-spring-beans-and-dependency-injection 를 참조하십시오.
코드를 깨끗하게 유지하기 위해 롬복 주석을 사용하는 것을 고려해 본 적이 있습니까? @RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Autowired 주석을 사용하여 생성자를 생성합니다.여기서 더 보기 https://projectlombok.org/features/Constructor.html
코드는 다음과 같습니다.
@Slf4j
@RequiredArgsConstructor
// MyCommandLineRunner.java
public class MyCommandLineRunner implements CommandLineRunner {
//final fields are included in the constructor generated by Lombok
private final DataSource ds;
@Override
public void run(String... args) throws Exception {
log.info("DataSource: {} ", ds.toString());
}
}
// Application.java
@SpringBootApplication
@RequiredArgsConstructor(onConstructor_={@Autowired}) // from JDK 8
// @RequiredArgsConstructor(onConstructor = @__(@Autowired)) // up to JDK 7
public class Application {
private final Datasource ds;
public static void main(String... args) {
SpringApplication.run(Application.class, args);
}
@Bean
public MyCommandLineRunner schedulerRunner() {
return new MyCommandLineRunner(ds);
}
}
나중에 편집
Lombok이 없는 솔루션은 콩이 생성될 때 의존성을 주입하기 위해 Spring에 의존합니다.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
/**
* dependency ds is injected by Spring
*/
public MyCommandLineRunner schedulerRunner(DataSource ds) {
return new MyCommandLineRunner(ds);
}
}
// MyCommandLineRunner.java
public class MyCommandLineRunner implements CommandLineRunner {
private final Log logger = LogFactory.getLog(getClass());
private final DataSource ds;
public MyCommandLineRunner(DataSource ds){
this.ds = ds;
}
@Override
public void run(String... args) throws Exception {
logger.info("DataSource: "+ ds.toString());
}
}
언급URL : https://stackoverflow.com/questions/43174074/clean-code-where-should-autowired-be-applied
'programing' 카테고리의 다른 글
양식 제어를 위한 값 접근자 없음 (0) | 2023.07.05 |
---|---|
Git 인덱스에는 정확히 무엇이 포함되어 있습니까? (0) | 2023.07.05 |
클래스 생성자는 'new' 없이 호출할 수 없습니다. commonjs가 있는 typescript (0) | 2023.07.05 |
MongoDB - 값이 null이거나 X보다 작은 결과를 찾습니다. (0) | 2023.07.05 |
데이터 소스를 사용할 수 있을 때까지 스프링 재시도 연결 (0) | 2023.07.05 |