JavaRush /Blog Java /Random-MS /Musim bunga adalah untuk orang yang malas. Asas, konsep a...

Musim bunga adalah untuk orang yang malas. Asas, konsep asas dan contoh dengan kod. Bahagian 2

Diterbitkan dalam kumpulan
Dalam artikel lepas , saya menerangkan secara ringkas apa itu spring, apa itu tong dan konteks. Kini tiba masanya untuk mencuba bagaimana ia berfungsi. Musim bunga adalah untuk orang yang malas.  Asas, konsep asas dan contoh dengan kod.  Bahagian 2 - 1Saya akan melakukannya sendiri dalam Intellij Idea Enterprise Edition. Tetapi semua contoh saya juga harus berfungsi dalam Edisi Komuniti Idea Intellij percuma. Hanya jika anda melihat dalam tangkapan skrin bahawa saya mempunyai beberapa jenis tetingkap yang anda tidak miliki, jangan risau, ia tidak kritikal untuk projek ini :) Mula-mula, mari buat projek Maven kosong. Saya menunjukkan cara untuk melakukan ini dalam artikel (baca sehingga perkataan " Tiba masanya untuk mengubah projek maven kami menjadi projek web. ", selepas itu ia sudah menunjukkan cara membuat projek web, dan kami tidak memerlukan ini sekarang) Mari kita buat dalam folder src/main /java adalah beberapa pakej (dalam kes saya, saya memanggilnya " ru.javarush.info.fatfaggy.animals", anda boleh menamakannya apa sahaja yang anda mahu, cuma jangan lupa untuk menggantikannya dengan nama anda di tempat yang betul). Dan mari kita buat kelas Maindi mana kita akan membuat kaedah
public static void main(String[] args) {
    ...
}
Kemudian buka fail pom.xml dan tambah bahagian di sana dependencies. Sekarang kita pergi ke repositori Maven dan cari konteks musim bunga versi stabil terkini di sana, dan tampalkan apa yang kita dapat di dalam bahagian dependencies. Saya menerangkan proses ini dengan lebih terperinci dalam artikel ini (lihat bahagian " Menyambung kebergantungan dalam Maven "). Kemudian Maven sendiri akan mencari dan memuat turun kebergantungan yang diperlukan, dan pada akhirnya anda akan mendapat sesuatu seperti ini:
Musim bunga adalah untuk orang yang malas.  Asas, konsep asas dan contoh dengan kod.  Bahagian 2 - 2
Di tetingkap kiri anda boleh melihat struktur projek dengan pakej dan kelas Main. Tetingkap tengah menunjukkan rupa pom.xml saya. Saya juga menambah bahagian sifat di sana , di mana saya menunjukkan kepada Maven versi Java yang saya gunakan dalam kod sumber dan versi mana untuk dikompilasi. Ini hanya supaya saya tidak mendapat idea tentang amaran apabila memulakan bahawa versi lama Java sedang digunakan. Anda boleh melakukannya, anda tidak boleh) Di tetingkap kanan - anda boleh melihat bahawa walaupun kami hanya menyambung konteks musim bunga - ia secara automatik menambah teras, kacang, aop dan ekspresi. Adalah mungkin untuk menyambungkan setiap modul secara berasingan, mendaftarkan pergantungan dalam memori untuk setiap satu dengan petunjuk versi yang jelas, tetapi buat masa ini kami gembira dengan pilihan seperti sekarang. Sekarang mari buat pakej entities(entiti) dan buat 3 kelas di dalamnya: Cat, Dog, Parrot. Biarkan setiap haiwan mempunyai nama ( private String name, anda boleh hardcode beberapa nilai di sana), dan getter/setter adalah awam. Sekarang pergi ke kelas Maindan main()tulis sesuatu seperti ini dalam kaedah:
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());
}
Pertama, kami mencipta objek konteks, dan dalam pembina kami memberikannya nama pakej yang perlu diimbas untuk kehadiran kacang. Iaitu, Spring akan melalui pakej ini dan cuba mencari kelas yang ditandakan dengan anotasi khas yang memberitahu Spring bahawa ini adalah kacang. Selepas itu ia mencipta objek kelas ini dan meletakkannya dalam konteksnya. Selepas itu kita mendapat kucing dari konteks ini. Apabila menangani objek konteks, kami memintanya untuk memberi kami kacang (objek), dan menunjukkan kelas objek yang kami perlukan (di sini, dengan cara ini, anda boleh menentukan bukan sahaja kelas, tetapi juga antara muka). Selepas itu Spring mengembalikan objek kelas ini kepada kami, yang kami simpan ke dalam pembolehubah. Seterusnya, kami meminta Spring untuk mendapatkan kami kacang yang dipanggil "anjing". Apabila Spring mencipta objek kelas, Dogia akan memberikannya nama standard (jika nama kacang yang dicipta tidak dinyatakan secara eksplisit), iaitu nama kelas objek, hanya dengan huruf kecil. Oleh itu, memandangkan kelas kami dipanggil Dog, nama kacang tersebut ialah "anjing". Jika kita mempunyai objek di sana BufferedReader, maka Spring akan memberikannya nama lalai "bufferedReader". Dan oleh kerana dalam kes ini (di Java) tidak ada kepastian yang tepat tentang kelas apa objek sedemikian, ia hanya mengembalikan satu tertentu Object, yang kemudiannya kita hantar secara manual ke jenis yang kita perlukan Dog. Pilihan dengan petunjuk kelas yang jelas adalah lebih mudah. Nah, dalam kes ketiga, kita mendapat kacang mengikut kelas dan nama. Mungkin terdapat situasi di mana dalam konteksnya akan terdapat beberapa biji satu kelas, dan untuk menunjukkan kacang tertentu yang kita perlukan, kita nyatakan namanya. Oleh kerana kami juga menunjukkan kelas dengan jelas di sini, kami tidak lagi perlu menghantar. Penting!Jika ternyata Spring menjumpai beberapa biji mengikut keperluan yang kami nyatakan kepadanya, ia tidak akan dapat menentukan kacang mana yang hendak diberikan kepada kami dan akan membuang pengecualian. Oleh itu, cuba tunjukkan kepadanya setepat mungkin tong sampah yang anda perlukan, supaya situasi sedemikian tidak timbul. Jika Spring tidak menemui satu biji pun dalam konteksnya mengikut syarat anda, ia juga akan membuang pengecualian. Nah, kemudian kami hanya memaparkan nama haiwan kami pada skrin untuk memastikan bahawa ini sebenarnya objek yang kami perlukan. Tetapi jika kita menjalankan program sekarang, kita akan melihat bahawa Spring bersumpah bahawa ia tidak dapat mencari haiwan yang kita perlukan dalam konteksnya. Ini berlaku kerana dia tidak mencipta kacang ini. Seperti yang telah saya katakan, apabila Spring mengimbas kelas, ia mencari anotasi Spring "nya" di sana. Dan jika ia tidak menjumpainya, maka ia tidak menganggap kelas tersebut sebagai kelas yang dia perlu buat kacang. Untuk membetulkannya, cuma tambahkan anotasi @Componentdi hadapan kelas dalam kelas haiwan kami.
@Component
public class Cat {
	private String name = "Barsik";
	...
}
Tetapi bukan itu sahaja. Jika kita perlu menyatakan secara eksplisit kepada Spring bahawa kacang untuk kelas ini harus mempunyai nama tertentu, nama ini boleh ditunjukkan dalam kurungan selepas anotasi. Sebagai contoh, untuk Spring memberi nama yang kita perlukan kepada parrot-keshakacang nuri, yang mainkemudiannya kita akan menerima burung nuri ini, kita perlu melakukan sesuatu seperti ini:
@Component("parrot-kesha")
public class Parrot {
	private String name = "Kesha";
	...
}
Ini adalah titik keseluruhan konfigurasi automatik . Anda menulis kelas anda, menandai mereka dengan anotasi yang diperlukan, dan menunjukkan kepada Spring pakej dengan kelas anda, yang melaluinya ia pergi, mencari anotasi dan mencipta objek kelas tersebut. Ngomong-ngomong, Spring akan mencari bukan sahaja anotasi @Component, tetapi juga semua anotasi lain yang diwarisi daripada anotasi ini. Contohnya, @Controller, @RestController, @Service, @Repositorydan lain-lain, yang akan kita temui dalam artikel selanjutnya. Sekarang mari kita cuba lakukan perkara yang sama, tetapi menggunakan konfigurasi java . Mula-mula, mari kita alih keluar anotasi @Componentdaripada kelas kita. Untuk merumitkan tugas, mari kita bayangkan bahawa ini bukan kelas yang ditulis sendiri, yang boleh kita ubah suai dengan mudah, menambah sesuatu, termasuk anotasi. Seolah-olah kelas-kelas ini dibungkus dalam beberapa perpustakaan. Dalam kes ini, kami tidak boleh mengedit kelas ini dalam apa jua cara supaya ia diterima menjelang musim bunga. Tetapi kita memerlukan objek kelas ini! Di sini kita memerlukan konfigurasi java untuk mencipta objek tersebut. Sebagai permulaan, mari buat pakej, sebagai contoh configs, dan di dalamnya - kelas Java biasa, sebagai contoh, MyConfigdan tandakannya dengan anotasi@Configuration
@Configuration
public class MyConfig {
}
Sekarang kita perlu mengubah sedikit main()cara kita mencipta konteks dalam kaedah. Kami boleh sama ada secara langsung menentukan kelas kami dengan konfigurasi di sana:
ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class);
Jika kita mempunyai beberapa kelas yang berbeza di mana kita mencipta kacang dan kita ingin menyambung beberapa daripadanya sekaligus, kita hanya menunjukkannya di sana dipisahkan dengan koma:
ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class, MyAnotherConfig.class);
Nah, jika kami mempunyai terlalu banyak daripada mereka, dan kami ingin menyambungkannya sekaligus, kami hanya menunjukkan di sini nama pakej yang kami ada:
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals.configs");
Dalam kes ini, Spring akan melalui pakej ini dan mencari semua kelas yang ditandakan dengan anotasi @Configuration. Nah, sekiranya kami mempunyai program yang sangat besar di mana konfigurasi dibahagikan kepada pakej yang berbeza, kami hanya menunjukkan nama pakej dengan konfigurasi yang dipisahkan dengan koma:
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");
Nah, atau nama pakej yang lebih biasa kepada mereka semua:
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals");
Anda boleh melakukannya seperti yang anda mahu, tetapi nampaknya pilihan pertama, di mana anda hanya menentukan kelas dengan konfigurasi, paling sesuai dengan program kami. Apabila mencipta konteks, Spring akan mencari kelas tersebut yang ditandakan dengan anotasi @Configurationdan mencipta objek kelas ini dengan sendirinya. Selepas itu ia akan cuba memanggil kaedah dalam kelas ini yang ditandakan dengan anotasi @Bean, yang bermaksud kaedah tersebut akan mengembalikan kacang (objek) yang telah diletakkan dalam konteksnya. Nah, sekarang mari kita cipta kacang kucing, anjing dan burung kakak tua dalam kelas kita dengan konfigurasi java. Ini dilakukan dengan mudah:
@Bean
public Cat getCat() {
	return new Cat();
}
Ternyata kami sendiri yang mencipta kucing kami secara manual dan memberikannya kepada Spring, dan dia telah meletakkan objek kami ini dalam konteksnya. Memandangkan kami tidak menyatakan secara jelas nama kacang kami, Spring akan memberikan nama kacang yang sama dengan nama kaedah. Dalam kes kami, kacang kucing akan mempunyai nama " getCat". Tetapi oleh kerana dalam main-e kita masih mendapat kucing bukan dengan nama, tetapi mengikut kelas, maka dalam kes ini nama tong ini tidak penting kepada kita. Buat kacang dengan anjing dengan cara yang sama, tetapi perlu diingat bahawa Spring akan menamakan kacang sedemikian dengan nama kaedah. Untuk menamakan secara eksplisit kacang kami dengan burung nuri, hanya nyatakan namanya dalam kurungan selepas anotasi @Bean:
@Bean("parrot-kesha")
public Object weNeedMoreParrots() {
	return new Parrot();
}
Seperti yang anda lihat, di sini saya menunjukkan jenis nilai pulangan Object, dan memanggil kaedah apa-apa sahaja. Ini tidak menjejaskan nama kacang dalam apa-apa cara kerana kami menetapkannya secara eksplisit di sini. Tetapi lebih baik untuk menunjukkan jenis nilai pulangan dan nama kaedah bukan begitu sahaja, tetapi lebih kurang jelas. Hanya untuk diri sendiri, apabila anda membuka projek ini dalam setahun. :) Sekarang mari kita pertimbangkan situasi di mana untuk mencipta satu kacang kita perlu menggunakan kacang lain . Sebagai contoh, kita mahu nama kucing dalam kacang kucing terdiri daripada nama burung nuri dan tali "-killer". Tiada masalah!
@Bean
public Cat getCat(Parrot parrot) {
	Cat cat = new Cat();
	cat.setName(parrot.getName() + "-killer");
	return cat;
}
Di sini Spring akan melihat bahawa sebelum mencipta kacang ini, dia perlu memindahkan kacang nuri yang telah dibuat ke sini. Oleh itu, dia akan membina rangkaian panggilan kepada kaedah kami supaya kaedah untuk mencipta burung nuri dipanggil dahulu, dan kemudian meneruskan burung nuri ini kepada kaedah untuk mencipta kucing. Di sinilah perkara yang dipanggil suntikan kebergantungan berfungsi : Spring sendiri memberikan kacang nuri yang diperlukan kepada kaedah kami. Jika idea merungut tentang pembolehubah parrot, jangan lupa untuk menukar jenis pulangan dalam kaedah untuk mencipta burung nuri dari Objectkepada Parrot. Di samping itu, konfigurasi Java membolehkan anda melaksanakan sepenuhnya sebarang kod Java dalam kaedah untuk mencipta kacang. Anda benar-benar boleh melakukan apa sahaja: mencipta objek tambahan lain, memanggil sebarang kaedah lain, walaupun yang tidak ditandakan dengan anotasi musim bunga, membuat gelung, syarat - apa sahaja yang terlintas di fikiran! Semua ini tidak boleh dicapai menggunakan konfigurasi automatik, lebih-lebih lagi menggunakan konfigurasi xml. Sekarang mari kita lihat masalah yang lebih menyeronokkan. Dengan polimorfisme dan antara muka :) Mari buat antara muka WeekDaydan buat 7 kelas yang akan melaksanakan antara muka ini: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. Mari buat kaedah dalam antara muka String getWeekDayName()yang akan mengembalikan nama hari dalam minggu kelas yang sepadan. Iaitu, kelas Mondayakan mengembalikan " monday", dsb. Katakan tugas semasa melancarkan aplikasi kami ialah meletakkan kacang dalam konteks yang sepadan dengan hari semasa dalam minggu. Bukan semua kacang dari semua kelas yang melaksanakan WeekDayantara muka, tetapi hanya yang kita perlukan. Ia boleh dilakukan seperti ini:
@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();
	}
}
Di sini jenis nilai pulangan ialah antara muka kami, dan kaedah mengembalikan objek sebenar kelas pelaksanaan antara muka bergantung pada hari semasa dalam minggu. Sekarang dalam kaedah main()kita boleh melakukan ini:
WeekDay weekDay = context.getBean(WeekDay.class);
System.out.println("It's " + weekDay.getWeekDayName() + " today!");
Ia memberitahu saya bahawa hari ini adalah Ahad :) Saya pasti bahawa jika saya menjalankan program esok, objek yang sama sekali berbeza akan muncul dalam konteks. Sila ambil perhatian bahawa di sini kita mendapat kacang hanya dengan antara muka: context.getBean(WeekDay.class). Spring akan melihat dalam konteksnya untuk melihat biji mana yang melaksanakan antara muka sedemikian dan akan mengembalikannya. Nah, maka ternyata WeekDayterdapat objek jenis dalam pembolehubah jenis Sunday, dan polimorfisme, yang sudah biasa kepada kita semua, bermula apabila bekerja dengan pembolehubah ini. :) Dan beberapa perkataan tentang pendekatan gabungan , di mana beberapa kacang dicipta oleh Spring sendiri, menggunakan pengimbasan pakej untuk kehadiran kelas dengan anotasi @Component, dan beberapa kacang lain dicipta menggunakan konfigurasi java. Untuk melakukan ini, mari kita kembali kepada versi asal, apabila kelas Cat, Dogdan Parrottelah ditandakan dengan anotasi @Component. Katakan kita ingin mencipta tong untuk haiwan kita menggunakan pengimbasan automatik pakej entitiesmenjelang musim bunga, tetapi mencipta tong dengan hari dalam seminggu seperti yang kita buat. Apa yang anda perlu lakukan ialah menambah pada peringkat kelas MyConfig, yang kami tentukan semasa mencipta konteks dalam main-th anotasi @ComponentScan, dan menunjukkan dalam kurungan pakej yang perlu diimbas dan biji kelas yang diperlukan dibuat secara automatik:
@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();
		}
	}
}
Ternyata apabila mencipta konteks, Spring melihat bahawa ia perlu memproses kelas MyConfig. Dia masuk ke dalamnya dan melihat bahawa dia perlu mengimbas pakej " ru.javarush.info.fatfaggy.animals.entities" dan mencipta kacang bagi kelas tersebut, selepas itu dia melaksanakan kaedah getDay()dari kelas MyConfigdan menambah jenis kacang WeekDaypada konteksnya. Dalam kaedah ini, main()kami kini mempunyai akses kepada semua kacang yang kami perlukan: kedua-dua objek haiwan dan kacang dengan hari dalam seminggu. Bagaimana untuk memastikan Spring juga mengambil beberapa konfigurasi xml - google sendiri di Internet jika perlu :) Ringkasan:
  • cuba gunakan konfigurasi automatik;
  • semasa konfigurasi automatik, kami menunjukkan nama pakej yang mengandungi kelas yang kacangnya perlu dibuat;
  • kelas sedemikian ditandakan dengan anotasi@Component;
  • spring melalui semua kelas tersebut dan mencipta objek mereka dan meletakkannya dalam konteks;
  • jika konfigurasi automatik tidak sesuai dengan kami atas sebab tertentu, kami menggunakan konfigurasi java;
  • dalam kes ini, kami mencipta kelas Java biasa yang kaedahnya akan mengembalikan objek yang kami perlukan, dan menandakan kelas sedemikian dengan anotasi @Configurationsekiranya kami mengimbas keseluruhan pakej dan bukannya menentukan kelas tertentu dengan konfigurasi semasa mencipta konteks;
  • kaedah kelas ini yang mengembalikan kacang ditandakan dengan anotasi @Bean;
  • jika kami ingin mendayakan pengimbasan automatik apabila menggunakan konfigurasi java, kami menggunakan anotasi @ComponentScan.
Jika tiada yang jelas, cuba baca artikel ini dalam beberapa hari. Nah, atau jika anda berada di peringkat awal Javarash, maka mungkin agak awal untuk anda belajar musim bunga. Anda sentiasa boleh kembali ke artikel ini sedikit kemudian, apabila anda berasa lebih yakin dalam pengaturcaraan di Java. Jika semuanya jelas, anda boleh cuba memindahkan beberapa projek haiwan kesayangan anda ke Spring :) Jika ada yang jelas, tetapi ada yang tidak begitu banyak, sila komen :) Terdapat juga cadangan dan komen jika saya melangkah ke suatu tempat atau saya menulis sesuatu yang bodoh ) Dalam artikel seterusnya kami akan menyelam lebih dalam ke spring-web-mvc dan membuat aplikasi web mudah menggunakan spring.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION