JavaRush /Java Blog /Random-KO /봄은 게으른 자의 것이다. 코드가 포함된 기본, 기본 개념 및 예제입니다. 2 부
Стас Пасинков
레벨 26
Киев

봄은 게으른 자의 것이다. 코드가 포함된 기본, 기본 개념 및 예제입니다. 2 부

Random-KO 그룹에 게시되었습니다
지난 기사에서 나는 스프링이 무엇인지, 빈이 무엇인지, 그리고 컨텍스트가 무엇인지 간단히 설명했습니다. 이제 모든 것이 어떻게 작동하는지 시험해 볼 시간입니다. 봄은 게으른 자의 것이다.  코드가 포함된 기본, 기본 개념 및 예제입니다.  파트 2 - 1Intellij Idea Enterprise Edition에서 직접 해보겠습니다. 그러나 모든 예제는 무료 Intellij Idea Community Edition에서도 작동해야 합니다. 스크린샷에서 여러분에게는 없는 창이 보이더라도 걱정하지 마세요. 이 프로젝트에서는 중요하지 않습니다. :) 먼저 빈 Maven 프로젝트를 생성해 보겠습니다. 나는 기사에서 이 작업을 수행하는 방법을 보여주었습니다 . (“ Maven 프로젝트를 웹 프로젝트로 전환할 시간입니다. ”라는 단어가 나올 때까지 읽으십시오. 그 후에 웹 프로젝트를 만드는 방법이 이미 나와 있으므로 지금은 필요하지 않습니다.) src/main 폴더 에 생성해 보겠습니다. /java는 일부 패키지입니다(제 경우에는 " "라고 불렀습니다 ru.javarush.info.fatfaggy.animals. 원하는 대로 이름을 지정할 수 있습니다. 올바른 위치에 이름을 바꾸는 것을 잊지 마세요). Main그리고 메서드를 만들 클래스를 만들어 보겠습니다.
public static void main(String[] args) {
    ...
}
그런 다음 pom.xml 파일을 열고 여기에 섹션을 추가합니다 dependencies. 이제 Maven 저장소 로 이동하여 최신 안정 버전의 스프링 컨텍스트를 찾아 섹션에 붙여넣습니다 dependencies. 이 기사에서 이 프로세스를 좀 더 자세히 설명했습니다 (" Maven에서 종속성 연결 " 섹션 참조 ). 그러면 Maven 자체가 필요한 종속성을 찾아 다운로드하고 결국 다음과 같은 결과를 얻게 됩니다.
봄은 게으른 자의 것이다.  코드가 포함된 기본, 기본 개념 및 예제입니다.  파트 2 - 2
왼쪽 창에서는 패키지와 클래스가 포함된 프로젝트의 구조를 볼 수 있습니다 Main. 가운데 창에는 내 pom.xml의 모양이 표시됩니다. 또한 거기에 속성 섹션을 추가하여 소스 코드에서 사용하고 있는 Java 버전과 컴파일할 버전을 Maven에 표시했습니다. 이는 시작할 때 이전 버전의 Java가 사용되고 있다는 경고가 표시되지 않도록 하기 위한 것입니다. 할 수 있고 할 수 없음) 오른쪽 창에서 - 스프링 컨텍스트만 연결했음에도 불구하고 자동으로 코어, 빈, AOP 및 표현식이 추가된 것을 볼 수 있습니다. 버전을 명시적으로 표시하여 메모리에 각 모듈에 대한 종속성을 등록하여 각 모듈을 별도로 연결하는 것이 가능했지만 지금은 이 옵션에 만족합니다. 이제 패키지(엔티티)를 생성 하고 entities그 안에 Cat, , 3개의 클래스를 생성해 보겠습니다 Dog. Parrot각 동물에게 이름을 부여하고( private String name여기에 일부 값을 하드코딩할 수 있음) getter/setter는 공개됩니다. 이제 클래스로 이동하여 Main메소드 main()에 다음과 같이 작성하십시오.
public static void main(String[] args) {
	// create an empty spring context that will search for its beans by annotations in the specified package
	ApplicationContext context =
		new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals.entities");

	Cat cat = context.getBean(Cat.class);
	Dog dog = (Dog) context.getBean("dog");
	Parrot parrot = context.getBean("parrot-kesha", Parrot.class);

	System.out.println(cat.getName());
	System.out.println(dog.getName());
	System.out.println(parrot.getName());
}
먼저 컨텍스트 객체를 생성하고 생성자에 빈이 있는지 검사해야 하는 패키지 이름을 지정합니다. 즉, Spring은 이 패키지를 살펴보고 이것이 Bean임을 Spring에 알리는 특수 주석이 표시된 클래스를 찾으려고 시도합니다. 그런 다음 이러한 클래스의 개체를 생성하고 해당 컨텍스트에 배치합니다. 그 후에 우리는 이 맥락에서 고양이를 얻습니다. 컨텍스트 객체를 다룰 때 우리는 빈(객체)을 제공하고 필요한 객체 클래스를 표시하도록 요청합니다(여기서는 클래스뿐만 아니라 인터페이스도 지정할 수 있습니다). 그 후 Spring은 이 클래스의 객체를 우리에게 반환하고 이를 변수에 저장합니다. 다음으로 우리는 Spring에게 "dog"이라는 빈을 가져와달라고 요청합니다. Spring이 클래스 객체를 생성할 때, Dog표준 이름(생성되는 빈의 이름이 명시적으로 지정되지 않은 경우)은 소문자로만 된 객체의 클래스 이름인 표준 이름을 제공합니다. 따라서 우리 클래스는 이라 불리기 때문에 Dog해당 빈의 이름은 "dog"이 될 것이다. 거기에 객체가 있으면 BufferedReaderSpring은 객체에 "bufferedReader"라는 기본 이름을 부여합니다. 그리고 이 경우(Java에서는) 해당 객체가 어떤 클래스인지 정확히 알 수 없기 때문에 단순히 특정 클래스를 반환한 Object다음 필요한 유형으로 수동으로 캐스팅합니다 Dog. 클래스를 명시적으로 표시하는 옵션이 더 편리합니다. 세 번째 경우에는 클래스와 이름별로 빈을 얻습니다. 컨텍스트에 한 클래스의 여러 Bean이 있는 상황이 있을 수 있으며, 어떤 특정 Bean이 필요한지 나타내기 위해 해당 Bean의 이름을 표시합니다. 여기서도 클래스를 명확하게 표시했기 때문에 더 이상 캐스팅할 필요가 없습니다. 중요한!Spring이 우리가 지정한 요구사항에 따라 여러 개의 빈을 찾은 것으로 밝혀지면 어떤 빈을 우리에게 제공할지 결정할 수 없으며 예외가 발생합니다. 따라서 그러한 상황이 발생하지 않도록 가능한 한 정확하게 어떤 쓰레기통이 필요한지 그에게 알려주십시오. Spring이 귀하의 조건에 따라 컨텍스트에서 단일 빈을 찾지 못하는 경우에도 예외가 발생합니다. 그런 다음 동물의 이름을 화면에 표시하여 이것이 실제로 우리에게 필요한 개체인지 확인합니다. 그러나 지금 프로그램을 실행하면 Spring이 컨텍스트에서 필요한 동물을 찾을 수 없다고 맹세하는 것을 볼 수 있습니다. 그가 이 콩을 만들지 않았기 때문에 이런 일이 일어났습니다. 내가 이미 말했듯이 Spring은 클래스를 스캔할 때 거기에서 "해당" Spring 주석을 찾습니다. 그리고 그것을 찾지 못하면 빈을 생성해야 하는 클래스와 같은 클래스를 인식하지 못합니다. @Component이 문제를 해결하려면 동물 클래스의 클래스 앞에 주석을 추가하면 됩니다 .
@Component
public class Cat {
	private String name = "Barsik";
	...
}
하지만 그게 전부는 아닙니다. 이 클래스의 Bean이 특정 이름을 가져야 함을 Spring에 명시적으로 표시해야 하는 경우 이 이름은 주석 뒤의 괄호 안에 표시될 수 있습니다. parrot-kesha예를 들어, Spring이 나중에 이 앵무새를 받게 될 앵무새 저장소에 필요한 이름을 지정하려면 main다음과 같이 해야 합니다.
@Component("parrot-kesha")
public class Parrot {
	private String name = "Kesha";
	...
}
이것이 자동 구성의 핵심입니다 . 클래스를 작성하고, 필요한 주석으로 표시하고, 클래스가 포함된 패키지를 Spring에 표시하면 패키지가 주석을 찾고 해당 클래스의 객체를 생성합니다. 그런데 Spring은 주석뿐만 아니라 @Component이 주석에서 상속된 다른 모든 주석도 검색합니다. 예를 들어, @Controller, @RestController, 및 기타 항목 @Service@Repository추가 기사에서 만나보겠습니다. 이제 java 구성을 사용하여 동일한 작업을 수행해 보겠습니다 . @Component먼저 클래스에서 주석을 제거해 보겠습니다 . 작업을 복잡하게 만들기 위해 이것이 우리가 쉽게 수정하고 주석을 포함하여 무언가를 추가할 수 있는 자체 작성 클래스가 아니라고 상상해 보겠습니다. 마치 이 수업들이 어떤 도서관에 빽빽이 들어차 있는 것 같습니다. 이 경우 봄에 허용되도록 이러한 클래스를 편집할 수 없습니다. 하지만 우리에게는 이러한 클래스의 객체가 필요합니다! 여기서 이러한 객체를 생성하려면 Java 구성이 필요합니다. 먼저 패키지(예: configs일반 Java 클래스)를 만들고 MyConfig주석으로 표시해 보겠습니다.@Configuration
@Configuration
public class MyConfig {
}
main()이제 메서드에서 컨텍스트를 생성하는 방식을 약간 조정해야 합니다 . 구성을 사용하여 클래스를 직접 지정할 수 있습니다.
ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class);
빈을 생성하는 여러 다른 클래스가 있고 그 중 여러 개를 한 번에 연결하려면 간단히 쉼표로 구분하여 표시하면 됩니다.
ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class, MyAnotherConfig.class);
글쎄, 너무 많아서 한 번에 모두 연결하려면 여기에 해당 패키지의 이름을 표시하면 됩니다.
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals.configs");
이 경우 Spring은 이 패키지를 살펴보고 주석으로 표시된 모든 클래스를 찾습니다 @Configuration. 음, 구성이 여러 패키지로 나누어져 있는 매우 큰 프로그램이 있는 경우 구성을 쉼표로 구분하여 패키지 이름을 표시하면 됩니다.
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals.database.configs",
		"ru.javarush.info.fatfaggy.animals.root.configs",
		"ru.javarush.info.fatfaggy.animals.web.configs");
글쎄, 또는 그들 모두에게 더 일반적인 패키지 이름은 다음과 같습니다.
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals");
원하는 대로 할 수 있지만 구성을 사용하여 클래스를 지정하는 첫 번째 옵션이 우리 프로그램에 가장 적합한 것 같습니다. 컨텍스트를 생성할 때 Spring은 주석으로 표시된 클래스를 검색 @Configuration하고 자체적으로 이러한 클래스의 객체를 생성합니다. 그런 다음 주석으로 표시된 이러한 클래스의 메서드를 호출하려고 시도합니다 @Bean. 이는 해당 메서드가 이미 해당 컨텍스트에 배치된 빈(객체)을 반환한다는 의미입니다. 자, 이제 Java 구성을 사용하여 클래스에 고양이, 개, 앵무새 콩을 만들어 보겠습니다. 이는 매우 간단하게 수행됩니다.
@Bean
public Cat getCat() {
	return new Cat();
}
우리는 수동으로 고양이를 직접 만들어 Spring에 주었고, 그는 이미 우리의 이 개체를 자신의 컨텍스트에 배치했습니다. 빈의 이름을 명시적으로 지정하지 않았으므로 Spring은 빈에 메서드 이름과 동일한 이름을 부여합니다. 우리의 경우 고양이 콩의 이름은 " getCat"입니다. 그러나 -e에서 main우리는 여전히 이름이 아닌 클래스별로 고양이를 얻으므로 이 경우 이 저장소의 이름은 우리에게 중요하지 않습니다. 같은 방법으로 개와 함께 빈을 만들지만 Spring은 메소드 이름으로 해당 빈의 이름을 지정한다는 점을 명심하세요. 앵무새로 빈의 이름을 명시적으로 지정하려면 주석 뒤의 괄호 안에 이름을 표시하면 됩니다 @Bean.
@Bean("parrot-kesha")
public Object weNeedMoreParrots() {
	return new Parrot();
}
보시다시피 여기서는 반환 값의 유형을 표시 Object하고 메서드를 무엇이든 호출했습니다. 여기서 명시적으로 설정했기 때문에 이는 어떤 방식으로든 Bean 이름에 영향을 주지 않습니다. 그러나 반환 값 유형과 메서드 이름을 갑자기 표시하는 것이 아니라 어느 정도 명확하게 표시하는 것이 좋습니다. 1년 뒤에 이 프로젝트를 열면 당신 자신을 위해서라도요. :) 이제 하나의 Bean을 생성하기 위해 다른 Bean을 사용해야 하는 상황을 고려해 보겠습니다 . 예를 들어, cat bean의 고양이 이름이 앵무새 이름과 "-killer"라는 문자열로 구성되기를 원합니다. 괜찮아요!
@Bean
public Cat getCat(Parrot parrot) {
	Cat cat = new Cat();
	cat.setName(parrot.getName() + "-killer");
	return cat;
}
여기에서 Spring은 이 빈을 생성하기 전에 이미 생성된 앵무새 빈을 여기에 전송해야 한다는 것을 알게 될 것입니다. 따라서 그는 앵무새를 생성하는 메서드가 먼저 호출되도록 메서드에 대한 호출 체인을 구축한 다음 이 앵무새를 고양이를 생성하는 메서드에 전달합니다. 이것이 종속성 주입 이라는 것이 작동하는 곳입니다 . Spring 자체가 필요한 앵무새 빈을 우리 메서드에 전달했습니다. 아이디어가 변수에 대해 불평하는 경우 앵무새 parrot생성 방법의 반환 유형을 에서 로 변경하는 것을 잊지 마십시오 . 또한 Java 구성을 사용하면 Bean 생성을 위한 메소드에서 모든 Java 코드를 절대적으로 실행할 수 있습니다 . 실제로 무엇이든 할 수 있습니다. 다른 보조 객체 생성, 다른 메서드 호출(스프링 주석으로 표시되지 않은 메서드 포함), 루프 만들기, 조건 등 마음에 떠오르는 모든 것이 가능합니다! 이 모든 것은 자동 구성을 사용하여 달성할 수 없으며 xml 구성을 사용하는 경우는 더욱 그렇습니다. ObjectParrot 이제 좀 더 재미있는 문제를 살펴보겠습니다. 다형성과 인터페이스를 사용하여 :) 인터페이스를 만들고 WeekDay이 인터페이스를 구현하는 7개의 클래스를 만들어 보겠습니다. Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. String getWeekDayName()해당 클래스의 요일 이름을 반환하는 메서드를 인터페이스에 만들어 보겠습니다 . 즉, 클래스는 " " 등을 Monday반환합니다 . monday애플리케이션을 실행할 때의 작업이 현재 요일에 해당하는 컨텍스트에 Bean을 배치하는 것이라고 가정해 보겠습니다. 인터페이스를 구현하는 모든 클래스의 모든 빈이 아니라 WeekDay우리에게 필요한 빈만 해당됩니다. 다음과 같이 할 수 있습니다:
@Bean
public WeekDay getDay() {
	DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
	switch (dayOfWeek) {
		case MONDAY: return new Monday();
		case TUESDAY: return new Tuesday();
		case WEDNESDAY: return new Wednesday();
		case THURSDAY: return new Thursday();
		case FRIDAY: return new Friday();
		case SATURDAY: return new Saturday();
		default: return new Sunday();
	}
}
여기서 반환 값 유형은 인터페이스이고, 메서드는 현재 요일에 따라 인터페이스 구현 클래스의 실제 개체를 반환합니다. 이제 메서드에서 main()다음을 수행할 수 있습니다.
WeekDay weekDay = context.getBean(WeekDay.class);
System.out.println("It's " + weekDay.getWeekDayName() + " today!");
오늘이 일요일이라고 하네요 :) 내일 프로그램을 실행하면 완전히 다른 객체가 컨텍스트에 나타날 것이라고 확신합니다. 여기서는 단순히 인터페이스를 통해 Bean을 얻는다는 점에 유의하세요 context.getBean(WeekDay.class). Spring은 해당 Bean 중 어떤 것이 그러한 인터페이스를 구현하고 이를 반환하는지 확인하기 위해 해당 컨텍스트를 조사합니다. 그러면 WeekDaytype 변수에 유형 객체가 있다는 것이 밝혀지고 Sunday, 이 변수를 사용할 때 이미 우리 모두에게 친숙한 다형성이 시작됩니다. :) 그리고 주석이 있는 클래스가 있는지 패키지를 검색하여 Spring 자체에서 일부 Bean을 생성하고 Java 구성을 사용하여 일부 다른 Bean을 생성하는 결합된 접근 방식 에 대해 몇 마디 설명합니다 . @Component이를 위해 클래스 및 가 주석으로 표시되었던 원래 버전 Cat으로 Dog돌아가 Parrot보겠습니다 @Component. 봄까지 패키지 자동 스캔을entities 사용하여 동물을 위한 상자를 생성 하고 방금 했던 것처럼 요일을 사용하여 상자를 생성 한다고 가정해 보겠습니다 . 당신이 해야 할 일은 -th 주석 MyConfig에서 컨텍스트를 생성할 때 지정하는 클래스 수준에 추가 하고, 검색해야 하는 패키지와 자동으로 생성되는 필수 클래스의 빈을 대괄호 안에 표시하는 것뿐입니다. main@ComponentScan
@Configuration
@ComponentScan("ru.javarush.info.fatfaggy.animals.entities")
public class MyConfig {
	@Bean
	public WeekDay getDay() {
		DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
		switch (dayOfWeek) {
			case MONDAY: return new Monday();
			case TUESDAY: return new Tuesday();
			case WEDNESDAY: return new Wednesday();
			case THURSDAY: return new Thursday();
			case FRIDAY: return new Friday();
			case SATURDAY: return new Saturday();
			default: return new Sunday();
		}
	}
}
컨텍스트를 생성할 때 Spring은 클래스를 처리해야 한다는 것을 알게 됩니다 MyConfig. 그는 그것에 들어가서 패키지 " ru.javarush.info.fatfaggy.animals.entities"를 스캔하고 해당 클래스의 Bean을 생성해야 한다는 것을 확인한 후 getDay()클래스에서 메소드를 실행 MyConfig하고 해당 유형의 Bean을 WeekDay자신의 컨텍스트에 추가합니다. 이 메서드에서 main()이제 필요한 모든 Bean, 즉 동물 객체와 요일 Bean에 액세스할 수 있습니다. Spring이 일부 XML 구성도 선택하는지 확인하는 방법 - 필요한 경우 인터넷에서 직접 Google에 검색해 보세요 :) 요약:
  • 자동 구성을 사용해 보십시오.
  • 자동 구성 중에 빈을 생성해야 하는 클래스가 포함된 패키지 이름을 나타냅니다.
  • 이러한 클래스에는 주석이 표시됩니다.@Component;
  • Spring은 그러한 모든 클래스를 거쳐 객체를 생성하고 컨텍스트에 배치합니다.
  • 어떤 이유로 자동 구성이 적합하지 않은 경우 Java 구성을 사용합니다.
  • 이 경우 필요한 객체를 반환하는 메소드가 있는 일반 Java 클래스를 생성하고 @Configuration컨텍스트를 생성할 때 구성으로 특정 클래스를 지정하는 대신 전체 패키지를 스캔하는 경우 주석으로 해당 클래스를 표시합니다.
  • Bean을 반환하는 이 클래스의 메서드는 주석으로 표시됩니다 @Bean.
  • Java 구성을 사용할 때 자동 스캔을 활성화하려면 주석을 사용합니다 @ComponentScan.
명확한 내용이 없다면 며칠 후에 이 기사를 읽어보세요. 글쎄, 또는 당신이 Javarash의 초기 수준에 있다면 아마도 봄을 배우기에는 조금 이르을 것입니다. 나중에 Java 프로그래밍에 좀 더 자신감을 갖게 되면 언제든지 이 기사를 다시 볼 수 있습니다. 모든 것이 명확하다면 애완동물 프로젝트 중 일부를 Spring으로 이전해 볼 수 있습니다 :) 뭔가 분명하지만 그다지 많지 않은 경우 댓글을 달아주세요 :) 어딘가에 갔거나 어리석은 내용을 썼다면 제안과 댓글도 있습니다 ) 다음 기사에서는 spring-web-mvc 에 대해 자세히 알아보고 spring을 사용하여 간단한 웹 애플리케이션을 만들어 보겠습니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION