CodeGym /Java Blogu /Rastgele /Tembel insanlar için bahar Vakfı, temel kavramlar ve kodl...
John Squirrels
Seviye
San Francisco

Tembel insanlar için bahar Vakfı, temel kavramlar ve kodlu örnekler. Bölüm 2

grupta yayınlandı
Bir önceki yazımda kısaca Baharın ne olduğunu, çekirdeklerin ve bağlamın ne olduğunu anlatmıştım. Şimdi deneme zamanı. Bunu IntelliJ IDEA Enterprise Edition kullanarak yapacağım. Ancak tüm örneklerim ücretsiz IntelliJ IDEA Community Edition'da da çalışmalıdır. Ekran görüntülerinde sizde olmayan bir pencerenin bende olduğunu görürseniz merak etmeyin — bu proje için önemli değil :) Tembel insanlar için bahar Vakfı, temel kavramlar ve kodlu örnekler.  Bölüm 2 - 1Önce boş bir Maven projesi oluşturun. Bunun nasıl yapıldığını bu linkteki yazıda gösterdim . " Maven projemizi bir web projesine dönüştürmenin zamanı geldi " sözlerine kadar okuyun - bundan sonra, makale bir web projesinin nasıl yapılacağını gösterir, ancak şu anda buna ihtiyacımız yok. src /main/java'daklasörünü açın, bir paket oluşturun (benim durumumda buna " adını verdim en.codegym.info.fatfaggy.animals. Onu istediğiniz gibi adlandırabilirsiniz. Tüm doğru yerlere benim paket adımı kendi paket adınızla değiştirmeyi unutmayın. Şimdi sınıfı oluşturun ve bir tane ekleyin Main. yöntem

public static void main(String[] args) {
    ...
}
Ardından pom.xml dosyasını açın ve bölümü ekleyin dependencies. Şimdi Maven deposuna gidin ve en son kararlı sürüm için Bahar bağlamını bulun. Bulduklarımızı bölüme koy dependencies. Bu süreci bu diğer CodeGym makalesinde daha ayrıntılı olarak anlattım (" Maven'de bağımlılıkları bağlama " başlıklı bölüme bakın ). Ardından Maven gerekli bağımlılıkları bulup indirecektir. Sonunda şöyle bir şey elde etmelisiniz: Tembel insanlar için bahar Vakfı, temel kavramlar ve kodlu örnekler.  Bölüm 2 - 2Soldaki pencerede, paket ve Mainsınıf ile proje yapısını görebilirsiniz. Orta pencere pom.xml'in benim için nasıl göründüğünü gösterir. Ayrıca bir özellik ekledimona bölüm. Bu bölüm, Maven'e kaynak dosyalarımda hangi Java sürümünü kullandığımı ve hangi sürümü derleyeceğimi söyler. Bu, IDEA'nın Java'nın eski bir sürümünü kullandığım konusunda beni uyarmaması içindir. Bu isteğe bağlıdır :) Sağ pencere, yalnızca spring-context modülünü bağlamamıza rağmen, spring-core, spring-beans, spring-aop ve spring-expression modüllerini otomatik olarak çektiğini açıkça ortaya koymaktadır. Pom.xml dosyasındaki açık sürümle her modül için bir bağımlılık yazarak her modülü ayrı ayrı bağlayabilirdik, ancak şimdilik her şeyin olduğu gibi olmasından memnunuz. Şimdi entitiespaketi oluşturun ve içinde 3 sınıf oluşturun: Cat, Dog, Parrot. Her hayvana bir isim verelim (private String name— orada bazı değerleri kodlayabilirsiniz). Alıcılar/belirleyiciler herkese açıktır. MainŞimdi sınıfa ve yönteme geçiyoruz main()ve şöyle bir şey yazıyoruz:

public static void main(String[] args) {
	// Create an empty Spring context that will look for its own beans based on the annotations in the specified package
	ApplicationContext context = 
		new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.entities");

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

	System.out.println(cat.getName());
	System.out.println(dog.getName());
	System.out.println(parrot.getName());
}
İlk olarak, kurucuya çekirdekleri bulmak için hangi paketi arayacağını söyleyen bir bağlam nesnesi yaratırız. Başka bir deyişle, Spring bu paketi inceleyecek ve fasulye olduklarını belirten özel açıklamalarla işaretlenmiş sınıfları bulmaya çalışacak. Daha sonra bu sınıfların nesnelerini oluşturur ve onları bağlama yerleştirir. Daha sonra bu bağlamdan bir kedi elde ediyoruz. Bağlam nesnesini bize istediğimiz nesnenin sınıfını belirten bir fasulye (nesne) vermesi için çağırıyoruz (bu arada, sadece sınıfları değil, arayüzleri de belirtebiliriz). Bundan sonra, Spring istenen sınıfın bir nesnesini döndürür ve onu bir değişkene kaydederiz. Sonra, Spring'den bize "köpek" adında bir fasulye almasını istiyoruz. Bahar oluşturduğundaDognesneye, sınıf adı olan ancak başlangıçtaki küçük harfle standart bir ad verir (oluşturulan bean'e açıkça bir ad atanmamışsa). Bu durumda sınıfımız çağrılır Dog, bu nedenle fasulyenin adı "köpek" olur. Orada bir nesneye ihtiyacımız olsaydı BufferedReader, Spring ona "bufferedReader" adını verirdi. Ve Java hangi sınıfı istediğimizden %100 emin olamadığı için, bir nesne döndürür Objectve bu nesneyi manuel olarak istenen türe dönüştürürüz, yani.Dog. Sınıfın açıkça belirtildiği seçenek daha uygundur. Üçüncü seçenek, sınıf adına ve fasulye adına göre bir fasulye elde etmektir. Bağlamın tek bir sınıftan birkaç çekirdeği olabilir. İhtiyacımız olan fasulyeyi belirtmek için adını belirtiyoruz. Burada sınıfı da açıkça belirttiğimiz için artık cast yapmamıza gerek kalmıyor. ÖNEMLİ!Spring, gereksinimlerimize uyan birkaç fasulye bulursa, bize hangi fasulyeyi vereceğini belirleyemez, bu nedenle bir istisna atar. Buna göre, bu durumu önlemek için, Spring'e hangi fasulyeye ihtiyacınız olduğunu söylerken mümkün olduğunca spesifik olmaya çalışmalısınız. Spring, bağlamını arar ve gereksinimlerimizle eşleşen tek bir çekirdek bulamazsa, o zaman da bir istisna atar. Son olarak, ihtiyacımız olan nesneleri gerçekten aldığımızı doğrulamak için hayvanlarımızın adlarını gösteriyoruz. Ancak programı şimdi çalıştırırsak, Bahar'ın mutsuz olduğunu görürüz - kendi bağlamında ihtiyacımız olan hayvanları bulamıyor. Bunun nedeni, bu çekirdekleri yaratmamış olmasıdır. Daha önce de söylediğim gibi, Spring sınıfları taradığında kendi Spring ek açıklamalarına bakar. Ve eğer Spring bu ek açıklamaları bulamazsa, o zaman Bu sınıfların yaratması gereken çekirdeklere karşılık geldiğini düşünmeyin. Bunu düzeltmek basitçe şunun eklenmesini gerektirir:@Componenthayvan sınıflarımızın her birinin önünde ek açıklama.

@Component
public class Cat {
	private String name = "Oscar";
	...
}
Ama dahası var. Spring'e açıkça bu sınıf için bean'in belirli bir adı olması gerektiğini söylememiz gerekirse, ek açıklamalardan sonra adı parantez içinde belirtiriz. parrot-pollyÖrneğin, Spring'e yöntemde bu papağanı elde etmek için kullanacağımız isim olan papağan çekirdeğine " " adını vermesini söylemek için mainşöyle bir şey yapmalıyız:

@Component("parrot-polly")
public class Parrot {
	private String name = "Polly";
	...
}
Otomatik yapılandırmanın bütün noktası budur . Sınıflarınızı yazarsınız, gerekli ek açıklamalarla işaretlersiniz ve Spring'e sınıflarınızın bulunduğu paketi söylersiniz. Bu, ek açıklamaları bulmak ve bu sınıfların nesnelerini oluşturmak için çerçevenin çalışacağı pakettir. @ComponentBu arada, Spring yalnızca ek açıklamaları değil, aynı zamanda bunu devralan diğer tüm ek açıklamaları da arar . Örneğin, @Controller, , , ve sonraki @RestControllermakalelerde tanıtacağımız daha fazlası. Şimdi aynı şeyi Java tabanlı yapılandırmayı kullanarak yapmaya çalışacağız . Başlamak için şunu kaldırın:@Service@Repository@Componentderslerimizden notlar. İşleri daha zor hale getirmek için, bu sınıfları bizim yazmadığımızı, bu nedenle onları kolayca değiştiremeyeceğimizi, yani ek açıklama ekleyemeyeceğimizi hayal edin. Sanki bu sınıflar bir kütüphanede paketlenmiş gibi. Bu durumda, bu sınıfları Spring tarafından tanınmaları için düzenlememizin bir yolu yoktur. Ama bu sınıfların nesnelerine ihtiyacımız var! Burada nesneleri oluşturmak için Java tabanlı konfigürasyona ihtiyacımız var. Başlamak için, gibi bir ada sahip bir paket oluşturun configs. Bu pakette, gibi sıradan bir Java sınıfı oluşturun MyConfigve notla işaretleyin @Configuration.

@Configuration
public class MyConfig {
}
main()Şimdi , bağlamı nasıl oluşturduğumuzu değiştirerek yöntemi değiştirmemiz gerekiyor . Hangi sınıfın yapılandırmamıza sahip olduğunu açıkça belirtebiliriz:

ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class);
Fasulye oluşturan birkaç farklı sınıfımız varsa ve bunlardan birkaçını aynı anda bağlamak istiyorsak, hepsini orada virgülle ayırarak belirtiriz:

ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class, MyAnotherConfig.class);
Ve eğer elimizde çok fazla varsa ve hepsini aynı anda bağlamak istiyorsak, o zaman sadece içerdikleri paketin adını belirtiriz:

ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.configs");
Bu durumda, Spring paketi gözden geçirecek ve ek @Configurationaçıklama ile işaretlenmiş tüm sınıfları bulacaktır. Pekala, konfigürasyonların farklı paketlere bölündüğü gerçekten büyük bir programımız varsa, o zaman konfigürasyonları içeren paketlerin adlarının virgülle ayrılmış bir listesini belirtiriz:

ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.database.configs",
		"en.codegym.info.fatfaggy.animals.root.configs",
		"en.codegym.info.fatfaggy.animals.web.configs");
Veya hepsi için ortak olan bir paketin adı:

ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals");
Bunu istediğiniz gibi yapabilirsiniz, ancak bana öyle geliyor ki, sadece yapılandırmaları olan bir sınıfı gösteren ilk seçenek programımıza en uygun olacak. Bir bağlam oluştururken, Spring ek açıklama ile işaretlenmiş sınıfları arar @Configurationve bu sınıflardan kendi nesnelerini oluşturur. Ek açıklama ile işaretlenmiş yöntemleri çağırmaya çalışır @Bean, bu da bu yöntemlerin Spring'in bağlama ekleyeceği fasulyeleri (nesneleri) döndürmesi anlamına gelir. Ve şimdi Java tabanlı yapılandırma ile sınıfımızda bir kedi, köpek ve papağan için fasulye oluşturacağız. Bunu yapmak oldukça basit:

@Bean
public Cat getCat() {
	return new Cat();
}
Burada kedimizi manuel olarak oluşturup Spring'e veriyoruz, o da nesnemizi bağlamında tutuyor. Fasulyemize açıkça bir isim vermediğimiz için, Spring ona metodun ismiyle aynı ismi verecektir. Bizim durumumuzda kedi fasulyesi " " olarak adlandırılacaktır getCat. Ancak yöntemde kedi çekirdeğini elde etmek için adı değil sınıfı kullandığımız için main, fasulyenin adı bizim için önemli değil. Benzer şekilde, Spring'in fasulyeye yöntem adını vereceğini akılda tutarak bir köpek fasulyesi oluşturun. Papağan fasulyemizi açıkça adlandırmak için, açıklamanın ardından adını parantez içinde belirtiyoruz @Bean:

@Bean("parrot-polly")
public Object weNeedMoreParrots() {
	return new Parrot();
}
Gördüğünüz gibi, burada bir Objectdönüş türü belirledim ve yönteme rastgele bir ad verdim. Bu, çekirdeğin adını etkilemez, çünkü adı burada açıkça belirttik. Yine de az çok anlamlı bir dönüş değeri ve yöntem adı belirtmek daha iyidir. Bunu, projeyi bir yıl içinde yeniden açtığınızda kendinize bir iyilik yapmaktan başka bir nedeniniz yoksa yapın. :) Şimdi, başka bir fasulye oluşturmak için bir fasulyeye ihtiyaç duyduğumuz durumu düşünün . Örneğin, kedi fasulyesindeki kedinin adının papağanın adı artı "-killer" dizesi olmasını istediğimizi varsayalım. Sorun değil!

@Bean
public Cat getCat(Parrot parrot) {
	Cat cat = new Cat();
	cat.setName(parrot.getName() + "-killer");
	return cat;
}
Burada Spring, bu çekirdeği oluşturmak için çerçevenin önceden oluşturulmuş papağan çekirdeğini geçmesi gerektiğini görecektir. Buna göre, gerekli yöntem çağrıları zincirini ayarlayacaktır: önce papağan oluşturma yöntemi çağrılır ve ardından çerçeve, yeni papağanı kedi oluşturma yöntemine geçirir. Bağımlılık enjeksiyonunun devreye girdiği yer burasıdır : Yay, gerekli papağan çekirdeğini yöntemimize aktarır. IDEA, değişken için üzülürse , papağan oluşturma yönteminin dönüş türünü olarak parrotdeğiştirmeyi unutmayın . Ek olarak, Java tabanlı yapılandırma, kesinlikle herhangi bir Java kodunu çalıştırmanıza izin verir.ObjectParrotfasulye oluşturma yöntemlerinizde. Gerçekten her şeyi yapabilirsiniz: başka yardımcı nesneler oluşturun, diğer yöntemleri çağırın, hatta Spring açıklamalarıyla işaretlenmemiş olanlar bile, döngüler oluşturun, Boole koşulları - aklınıza ne gelirse! Bu, otomatik yapılandırmayla mümkün değildir ve XML yapılandırmasıyla daha da azdır. Şimdi biraz daha eğlenceli olan bir problem düşünelim. Polimorfizm ve arayüzler :) Bir arayüz oluşturacağız WeekDayve bu arayüzü uygulayan 7 sınıf oluşturacağız: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. String getWeekDayName()Arayüze , ilgili sınıf için haftanın gününün adını döndürecek bir yöntem vereceğiz . Başka bir deyişle, Mondaysınıf geri dönecek "Monday" vb WeekDay. bunu şu şekilde yap:

@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();
	}
}
Buradaki dönüş tipi arayüzümüzdür. Yöntem, haftanın geçerli gününe bağlı olarak arabirimi uygulayan sınıflardan birinin gerçek bir nesnesini döndürür. Artık metodda şunları yapabiliriz main():

WeekDay weekDay = context.getBean(WeekDay.class);
System.out.println("Today is " + weekDay.getWeekDayName() + "!");
Benim için program bana bugünün Pazar olduğunu söylüyor :) Programı yarın çalıştırırsam, içeriğin tamamen farklı bir nesne içereceğinden eminim. Fasulyeyi sadece arayüzü kullanarak aldığımızı unutmayın: context.getBean(WeekDay.class). Spring, arayüzü uygulayan fasulye için bağlamını arayacak ve onu geri getirecektir. WeekDaySonra , değişkenimizin bir Sunday nesnesi ile bittiği ve bu değişkenle çalışırken tanıdık polimorfizm kavramının geçerli olduğu ortaya çıkıyor . :) Şimdi, bazı çekirdeklerin Spring tarafından otomatik olarak, bazılarının ek açıklamalı sınıflar için paketleri tarayarak ve diğerlerinin Java tabanlı yapılandırmayla oluşturulduğu birleşik yaklaşım hakkında birkaç söz . @ComponentBunu düşündüğümüzde, orijinal sürüme geri döneceğiz; burada Cat, Dog, veParrotsınıflar şerh ile işaretlenmiştir @Component. Spring'in paketi otomatik olarak taramasını sağlayarak hayvanlarımız için fasulye oluşturmak istediğimizi varsayalım entities, ancak aynı zamanda az önce yaptığımız gibi haftanın günü ile bir fasulye oluşturmak istiyoruz. Yapmanız gereken tek şey , içinde bağlamı oluştururken belirttiğimiz sınıf @ComponentScandüzeyinde ek açıklama eklemek ve taranması gereken paketi parantez içinde belirtmek ve gerekli sınıflardan bean'leri otomatik olarak oluşturmak: MyConfigmain()

@Configuration
@ComponentScan("en.codegym.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();
		}
	}
}
Bağlamı oluştururken, Spring sınıfı işlemesi gerektiğini görür MyConfig. Sınıfa girer ve " " paketi taraması ve bu sınıfların bean'lerini yaratması gerektiğini görür en.codegym.info.fatfaggy.animals.entities, ardından MyConfigsınıfın getDay()yöntemini yürütür ve WeekDaybağlama bir bean ekler. Yöntemde main()artık ihtiyacımız olan tüm fasulyelere erişimimiz var: hem hayvan nesneleri hem de haftanın günü olan bir fasulye. Spring'in bazı XML yapılandırma dosyalarını da almasını sağlamanız gerekirse, bir açıklama bulmak için kendi web aramanızı yapabilirsiniz :) Özet:
  • Otomatik yapılandırmayı kullanmayı deneyin
  • Otomatik yapılandırma sırasında, çekirdeklerinin oluşturulması gereken sınıfları içeren paketin adını belirtin.
  • @ComponentBu sınıflar ek açıklama ile işaretlenmiştir.
  • Spring, tüm bu sınıflardan geçer, nesneler yaratır ve onları bağlama yerleştirir;
  • Herhangi bir nedenle otomatik konfigürasyon bize uymuyorsa, Java tabanlı konfigürasyon kullanırız.
  • Bu durumda, yöntemleri ihtiyacımız olan nesneleri döndüren sıradan bir Java sınıfı yaratıyoruz. @ConfigurationBağlamı oluştururken yapılandırma ile belirli bir sınıfı belirtmek yerine tüm paketi tarayacaksak bu sınıfı ek açıklama ile işaretliyoruz.
  • @BeanFasulye döndüren bu sınıfın yöntemleri ek açıklama ile işaretlenmiştir.
  • Java tabanlı yapılandırmayı kullanırken otomatik taramayı etkinleştirmek istiyorsak ek @ComponentScanaçıklamayı kullanırız.
Bu makale tamamen kafa karıştırıcıysa, birkaç gün içinde okumayı deneyin. Ya da CodeGym'in ilk seviyelerinden birindeyseniz, Bahar'ı öğrenmeniz için biraz erken olabilir. Java programlama becerilerinize daha fazla güvendiğinizi hissettiğinizde bu makaleye biraz sonra geri dönebilirsiniz. Her şey açıksa, o zaman bazı evcil hayvan projelerinizi Bahar'a dönüştürmeyi deneyebilirsiniz :) Bazı şeyler net ama diğerleri değilse, o zaman lütfen yorum bırakın :) Önerilerinizi ve eleştirilerinizi, yanlış yaptıysam bana bildirin. bir yerlerde veya saçma sapan şeyler yazdık :) Bir sonraki yazıda aniden spring-web-mvc'ye dalacağız ve Spring kullanarak basit bir web uygulaması yapacağız.
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION