CodeGym /Java Blog /Random /Spring for lazy people Foundation, mga pangunahing konsep...
John Squirrels
Antas
San Francisco

Spring for lazy people Foundation, mga pangunahing konsepto, at mga halimbawa na may code. Bahagi 2

Nai-publish sa grupo
Sa nakaraang artikulo , maikli kong ipinaliwanag kung ano ang Spring at kung ano ang beans at konteksto. Ngayon ay oras na upang subukan ito. Gagawin ko ito gamit ang IntelliJ IDEA Enterprise Edition. Ngunit lahat ng aking mga halimbawa ay dapat ding gumana sa libreng IntelliJ IDEA Community Edition. Sa mga screenshot, kung nakita mong mayroon akong ilang window na wala ka, huwag mag-alala — hindi ito mahalaga para sa proyektong ito :) Spring for lazy people Foundation, mga pangunahing konsepto, at mga halimbawa na may code.  Bahagi 2 - 1Una, lumikha ng walang laman na proyekto ng Maven. Ipinakita ko kung paano gawin ito sa artikulo sa link na ito . Basahin hanggang sa mga salitang " Oras na para i-convert natin ang aming proyekto sa Maven sa isang proyekto sa web. " — pagkatapos nito, ipinapakita ng artikulo kung paano gumawa ng isang proyekto sa web, ngunit hindi namin iyon kailangan sa ngayon. Sa src/main/javafolder, lumikha ng isang pakete (sa aking kaso, tinawag ko itong " en.codegym.info.fatfaggy.animals. Maaari mo itong tawagan kahit anong gusto mo. Basta huwag kalimutang palitan ang aking pangalan ng pakete ng iyong pangalan ng pakete sa lahat ng tamang lugar. Ngayon lumikha ng Mainklase at magdagdag ng isang paraan

public static void main(String[] args) {
    ...
}
Pagkatapos nito, buksan ang pom.xml file at idagdag ang dependenciesseksyon. Pumunta ngayon sa repositoryo ng Maven at hanapin ang konteksto ng Spring para sa pinakabagong stable na bersyon. Ilagay ang nahanap namin sa dependenciesseksyon. Inilarawan ko ang prosesong ito nang mas detalyado sa ibang artikulo ng CodeGym na ito (tingnan ang seksyong pinamagatang " Pagkonekta ng mga dependency sa Maven "). Pagkatapos ay mahahanap at ida-download mismo ng Maven ang mga kinakailangang dependencies. Sa huli, dapat kang makakuha ng ganito: Spring for lazy people Foundation, mga pangunahing konsepto, at mga halimbawa na may code.  Bahagi 2 - 2Sa window sa kaliwa, makikita mo ang istraktura ng proyekto kasama ang pakete at ang Mainklase. Ipinapakita ng gitnang window kung paano ako hinahanap ng pom.xml. Nagdagdag din ako ng propertiesseksyon dito. Sinasabi ng seksyong ito kay Maven kung aling bersyon ng Java ang ginagamit ko sa aking mga source file at kung aling bersyon ang isasama. Ito ay para lang hindi ako bigyan ng babala ng IDEA na gumagamit ako ng lumang bersyon ng Java. Ito ay opsyonal :) Nilinaw ng tamang window na kahit na ikinonekta lang namin ang spring-context module, awtomatiko itong hinila sa spring-core, spring-beans, spring-aop at spring-expression na mga module. Maaari naming ikonekta ang bawat module nang hiwalay, na nagsusulat ng dependency para sa bawat module na may tahasang bersyon sa pom.xml file, ngunit sa ngayon ay masaya kami sa mga bagay kung ano ang mga ito. Ngayon lumikha ng entitiespackage at lumikha ng 3 mga klase dito: Cat, Dog, Parrot. Bigyan natin ng pangalan ang bawat hayop (private String name— maaari mong i-hardcode ang ilang mga halaga doon). Ang mga getter/setter ay pampubliko. Ngayon lumipat kami sa Mainklase at ang main()pamamaraan, at sumulat kami ng ganito:

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());
}
Una, lumikha kami ng isang bagay sa konteksto, na nagsasabi sa tagabuo kung aling pakete ang titingnan upang makahanap ng mga beans. Sa madaling salita, dadaan ang Spring sa package na ito at susubukang maghanap ng mga klase na may marka ng mga espesyal na anotasyon na nagpapahiwatig na sila ay beans. Pagkatapos ay lumilikha ito ng mga bagay ng mga klase na ito at inilalagay ang mga ito sa konteksto. Pagkatapos nito, nakakakuha kami ng pusa mula sa kontekstong ito. Tumawag kami sa object ng konteksto upang bigyan kami ng isang bean (object), na nagpapahiwatig ng klase ng bagay na gusto namin (sa pamamagitan ng paraan, maaari rin naming tukuyin ang mga interface, hindi lamang mga klase). Pagkatapos nito, ibinabalik ng Spring ang isang object ng hiniling na klase, na pagkatapos ay i-save namin sa isang variable. Susunod, hinihiling namin kay Spring na kumuha kami ng isang bean na tinatawag na "aso". Kapag ang Spring ay lumikha ng isangDogobject, binibigyan nito ang object ng karaniwang pangalan (maliban kung ang nilikhang bean ay tahasang binigyan ng pangalan), na siyang pangalan ng klase ngunit may paunang maliit na titik. Sa kasong ito, ang aming klase ay tinatawag na Dog, kaya ang pangalan ng bean ay "aso". Kung kailangan namin ng isang BufferedReaderbagay doon , ang Spring ay tatawagin itong "bufferedReader". At dahil hindi 100% tiyak ng Java kung aling klase ang gusto natin, ibinabalik nito ang isang Objectbagay, na kung saan manu-mano naming inihagis sa nais na uri, ibig sabihinDog. Ang opsyon kung saan ang klase ay tahasang ipinahiwatig ay mas maginhawa. Ang pangatlong opsyon ay ang kumuha ng bean ayon sa pangalan ng klase at sa pangalan ng bean. Posible na ang konteksto ay maaaring magkaroon ng ilang beans ng isang klase. Upang ipahiwatig ang partikular na bean na kailangan namin, ipinapahiwatig namin ang pangalan nito. Dahil tahasan din naming ipinapahiwatig ang klase dito, hindi na namin kailangang magsagawa ng cast. MAHALAGA!Kung makakita ang Spring ng ilang beans na tumutugma sa aming mga kinakailangan, hindi nito matukoy kung aling bean ang ibibigay sa amin, kaya magtapon ito ng exception. Alinsunod dito, upang maiwasan ang sitwasyong ito, dapat mong subukan na maging tiyak hangga't maaari sa pagsasabi sa Spring kung aling bean ang kailangan mo. Kung hahanapin ng Spring ang konteksto nito at nabigong makahanap ng isang bean na tumutugma sa aming mga kinakailangan, maglalagay din ito ng exception. Sa wakas, ipinapakita lang namin ang mga pangalan ng aming mga hayop upang i-verify na nakuha namin talaga ang mga bagay na kailangan namin. Ngunit kung patakbuhin natin ang programa ngayon, makikita natin na ang Spring ay hindi masaya — hindi nito mahanap ang mga hayop na kailangan natin sa konteksto nito. Ito ay dahil hindi nito nilikha ang mga beans na ito. Gaya ng sinabi ko dati, kapag nag-scan ng mga klase ang Spring, hinahanap nito ang sarili nitong mga anotasyon sa Spring. At kung hindi mahanap ng Spring ang mga anotasyong ito, hindi Tisipin na ang mga klaseng ito ay tumutugma sa mga beans na kailangan nitong likhain. Ang pag-aayos nito ay nangangailangan lamang ng pagdaragdag ng@Componentanotasyon sa harap ng bawat klase ng ating hayop.

@Component
public class Cat {
	private String name = "Oscar";
	...
}
Pero meron pa. Kung kailangan naming tahasang sabihin sa Spring na ang bean para sa klase na ito ay dapat magkaroon ng isang partikular na pangalan, ipinapahiwatig namin ang pangalan sa mga panaklong pagkatapos ng anotasyon. Halimbawa, para sabihin sa Spring na ibigay ang pangalang " parrot-polly" sa parrot bean, na siyang pangalang gagamitin namin para makuha ang parrot na ito sa mainpamamaraan, dapat kaming gumawa ng ganito:

@Component("parrot-polly")
public class Parrot {
	private String name = "Polly";
	...
}
Ito ang buong punto ng awtomatikong pagsasaayos . Isusulat mo ang iyong mga klase, markahan ang mga ito ng mga kinakailangang anotasyon, at sabihin sa Spring ang package na mayroon ang iyong mga klase. Ito ang package na tatakbo sa framework upang mahanap ang mga anotasyon at lumikha ng mga bagay ng mga klaseng ito. Siyanga pala, ang Spring ay hindi lamang naghahanap ng @Componentmga anotasyon, kundi pati na rin sa lahat ng iba pang anotasyon na nagmamana ng isang ito. Halimbawa, @Controller, @RestController, @Service, @Repository, at higit pa, na ipakikilala namin sa mga artikulo sa hinaharap. Ngayon ay susubukan naming gawin ang parehong bagay gamit ang Java-based na configuration . Upang makapagsimula, alisin ang@Componentmga anotasyon mula sa aming mga klase. Upang gawing mas mahirap ang mga bagay, isipin na hindi namin isinulat ang mga klase na ito, kaya hindi namin madaling baguhin ang mga ito, na nangangahulugang hindi kami makakapagdagdag ng mga anotasyon. Parang naka-package ang mga klaseng ito sa ilang library. Sa kasong ito, walang paraan para sa amin na i-edit ang mga klase na ito upang makilala sila ng Spring. Ngunit kailangan namin ng mga bagay ng mga klase na ito! Dito kailangan namin ng configuration na nakabatay sa Java upang malikha ang mga bagay. Upang makapagsimula, lumikha ng isang package na may pangalan tulad ng configs. Sa package na ito, lumikha ng isang ordinaryong Java class, tulad ng MyConfig, at markahan ito ng @Configurationanotasyon.

@Configuration
public class MyConfig {
}
Ngayon ay kailangan nating i-tweak ang main()pamamaraan, binabago kung paano tayo gumagawa ng konteksto. Maaari naming tahasang ipahiwatig kung aling klase ang may aming pagsasaayos:

ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class);
Kung mayroon kaming iba't ibang klase na lumilikha ng beans at gusto naming ikonekta ang ilan sa mga ito nang sabay-sabay, ipinapahiwatig lang namin ang lahat doon, na pinaghihiwalay ng mga kuwit:

ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class, MyAnotherConfig.class);
At kung marami kami sa kanila at gusto naming ikonekta silang lahat nang sabay-sabay, ipinapahiwatig lang namin ang pangalan ng package na nilalaman ng mga ito:

ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals.configs");
Sa kasong ito, dadaan ang Spring sa package at hahanapin ang lahat ng klase na minarkahan ng @Configurationanotasyon. Well, at kung mayroon kaming isang malaking programa kung saan ang mga pagsasaayos ay nahahati sa iba't ibang mga pakete, pagkatapos ay ipinapahiwatig lamang namin ang isang listahan ng mga pangalan ng mga pangalan ng mga pakete na naglalaman ng mga pagsasaayos:

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");
O ang pangalan ng isang package na karaniwan para sa kanilang lahat:

ApplicationContext context =
	new AnnotationConfigApplicationContext("en.codegym.info.fatfaggy.animals");
Magagawa mo ito gayunpaman gusto mo, ngunit tila sa akin na ang pinakaunang opsyon, na nagpapahiwatig lamang ng isang klase na may mga pagsasaayos, ay pinakaangkop sa aming programa. Kapag gumagawa ng konteksto, hinahanap ng Spring ang mga klase na may marka ng @Configurationanotasyon at gagawa ng sarili nitong mga bagay ng mga klaseng ito. Sinusubukan nitong tawagan ang mga pamamaraan na may markang @Beananotasyon, na nangangahulugan na ang mga pamamaraang ito ay nagbabalik ng mga beans (mga bagay) na idaragdag ng Spring sa konteksto. At ngayon gagawa kami ng beans para sa isang pusa, aso, at loro sa aming klase na may configuration na nakabatay sa Java. Ito ay medyo simpleng gawin:

@Bean
public Cat getCat() {
	return new Cat();
}
Dito, manu-mano naming ginagawa ang aming pusa at ibinibigay ito sa Spring, na pagkatapos ay hawak ang aming bagay sa konteksto nito. Dahil hindi namin tahasang binigyan ng pangalan ang aming bean, bibigyan ito ng Spring ng parehong pangalan bilang ang pangalan ng pamamaraan. Sa aming kaso, ang cat bean ay tatawaging " getCat". Ngunit dahil ginagamit namin ang klase, hindi ang pangalan, upang makuha ang cat bean sa mainpamamaraan, ang pangalan ng bean ay hindi mahalaga sa amin. Katulad nito, lumikha ng isang dog bean, isinasaisip na ang Spring ay magbibigay ng pangalan ng pamamaraan sa bean. Upang tahasang pangalanan ang aming parrot bean, ipinapahiwatig lang namin ang pangalan nito sa mga panaklong pagkatapos ng @Beananotasyon:

@Bean("parrot-polly")
public Object weNeedMoreParrots() {
	return new Parrot();
}
Tulad ng nakikita mo, dito ko ipinahiwatig ang isang Objecturi ng pagbabalik at binigyan ang pamamaraan ng isang arbitrary na pangalan. Hindi ito nakakaapekto sa pangalan ng bean, dahil tahasan naming tinukoy ang pangalan dito. Gayunpaman, mas mainam na magpahiwatig ng mas marami o hindi gaanong makabuluhang halaga ng pagbabalik at pangalan ng pamamaraan. Gawin ito kung walang ibang dahilan kundi gawin ang iyong sarili ng isang pabor kapag binuksan mo muli ang proyekto sa isang taon. :) Ngayon isaalang-alang ang sitwasyon kung saan kailangan namin ng isang bean upang lumikha ng isa pang bean . Halimbawa, ipagpalagay na gusto namin ang pangalan ng pusa sa cat bean ay ang pangalan ng loro kasama ang string na "-killer". Walang problema!

@Bean
public Cat getCat(Parrot parrot) {
	Cat cat = new Cat();
	cat.setName(parrot.getName() + "-killer");
	return cat;
}
Dito makikita ng Spring na upang malikha ang bean na ito, ang balangkas ay kailangang pumasa sa naunang nilikha na parrot bean. Alinsunod dito, aayusin nito ang kinakailangang hanay ng mga tawag sa pamamaraan: una, ang paraan ng paglikha ng parrot ay tinatawag at pagkatapos ay ipinapasa ng balangkas ang bagong loro sa paraan ng paglikha ng pusa. Dito gumaganap ang dependency injection : Spring mismo ang nagpapasa ng kinakailangang parrot bean sa aming pamamaraan. Kung magalit ang IDEA tungkol sa parrotvariable, huwag kalimutang baguhin ang uri ng pagbabalik ng paraan ng paggawa ng parrot mula Objectsa Parrot. Bilang karagdagan, ang Java-based na configuration ay nagbibigay-daan sa iyong patakbuhin ang anumang Java codesa iyong mga pamamaraan sa paggawa ng bean. Maaari mo talagang gawin ang anumang bagay: lumikha ng iba pang mga auxiliary na bagay, tumawag sa anumang iba pang mga pamamaraan, kahit na ang mga hindi minarkahan ng Spring annotation, lumikha ng mga loop, Boolean na kundisyon — anuman ang naiisip! Hindi lahat ito ay posible sa awtomatikong pagsasaayos, at mas mababa pa sa XML configuration. Ngayon isaalang-alang natin ang isang problema na medyo mas masaya. Polymorphism at mga interface :) Gagawa kami ng WeekDayinterface at gagawa kami ng 7 klase na nagpapatupad ng interface na ito: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. Bibigyan namin ang interface ng isang String getWeekDayName()paraan, na magbabalik ng pangalan ng araw ng linggo para sa kaukulang klase. Sa madaling salita, Mondaybabalik ang klase "Monday", atbp. Sa pagsisimula ng application, ipagpalagay na ang aming gawain ay maglagay ng bean na tumutugma sa kasalukuyang araw ng linggo sa konteksto. Hindi beans para sa lahat ng klase na nagpapatupad ng interface — ang isang bean lang na kailangan namin. Maaari WeekDaykang gawin iyan tungkol sa ganito:

@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();
	}
}
Narito ang uri ng pagbabalik ay ang aming interface. Ang pamamaraan ay nagbabalik ng isang bona fide object ng isa sa mga klase na nagpapatupad ng interface, depende sa kasalukuyang araw ng linggo. Ngayon ay maaari nating gawin ang sumusunod sa main()pamamaraan:

WeekDay weekDay = context.getBean(WeekDay.class);
System.out.println("Today is " + weekDay.getWeekDayName() + "!");
Para sa akin, ang programa ay nagsasabi sa akin na ito ay Linggo :) Kumpiyansa ako na kung patakbuhin ko ang programa bukas, ang konteksto ay maglalaman ng isang ganap na naiibang bagay. Tandaan na nakukuha namin ang bean gamit lamang ang interface: context.getBean(WeekDay.class). Hahanapin ng Spring ang konteksto nito para sa bean na nagpapatupad ng interface, at ibabalik ito. Pagkatapos ay lumalabas na ang aming WeekDayvariable ay nagtatapos sa isang bagay sa Linggo, at ang pamilyar na konsepto ng polymorphism ay nalalapat habang nagtatrabaho kami sa variable na ito. :) Ngayon ang ilang mga salita tungkol sa pinagsamang diskarte , kung saan ang ilang mga bean ay awtomatikong nilikha ng Spring, ang ilan ay sa pamamagitan ng pag-scan ng mga pakete para sa mga klase na may @Componentanotasyon, at ang iba sa pamamagitan ng Java-based na configuration. Habang isinasaalang-alang namin ito, babalik kami sa orihinal na bersyon, kung saan ang Cat, Dog, atParrotang mga klase ay minarkahan ng @Componentanotasyon. Ipagpalagay na gusto naming gumawa ng beans para sa aming mga hayop sa pamamagitan ng awtomatikong pag-scan ng Spring sa entitiespackage, ngunit gusto rin naming gumawa ng bean sa araw ng linggo, tulad ng ginawa namin. Ang kailangan mo lang gawin ay idagdag ang @ComponentScananotasyon sa antas ng MyConfigklase, na ipinapahiwatig namin kapag lumilikha ng konteksto sa main(), at ipahiwatig sa panaklong ang package na kailangang i-scan at awtomatikong lumikha ng beans ng mga kinakailangang klase:

@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();
		}
	}
}
Kapag lumilikha ng konteksto, nakikita ng Spring na kailangan nitong iproseso ang MyConfigklase. Pumasok ito sa klase at nakitang kailangan nitong i-scan ang en.codegym.info.fatfaggy.animals.entitiespackage na " " at lumikha ng mga beans ng mga klaseng iyon, pagkatapos nito isagawa ang pamamaraan MyConfigng klase getDay()at magdagdag ng WeekDaybean sa konteksto. Sa main()pamamaraan, mayroon na kaming access sa lahat ng beans na kailangan namin: parehong mga bagay na hayop at isang bean na may araw ng linggo. Kung sakaling kailanganin mong kunin din ang Spring ng ilang XML configuration file, maaari mong gawin ang iyong sariling paghahanap sa web upang makahanap ng paliwanag :) Buod:
  • Subukang gumamit ng awtomatikong pagsasaayos
  • Sa panahon ng awtomatikong pagsasaayos, ipahiwatig ang pangalan ng pakete na naglalaman ng mga klase na ang mga bean ay kailangang gawin
  • Ang mga klase na ito ay minarkahan ng @Componentanotasyon
  • Ang Spring ay tumatakbo sa lahat ng mga klase na ito, lumilikha ng mga bagay, at inilalagay ang mga ito sa konteksto;
  • Kung hindi angkop sa amin ang awtomatikong pagsasaayos sa ilang kadahilanan, gumagamit kami ng configuration na nakabatay sa Java
  • Sa kasong ito, lumikha kami ng isang ordinaryong Java class na ang mga pamamaraan ay nagbabalik ng mga bagay na kailangan namin. Minarkahan namin ang klase na ito ng @Configurationanotasyon kung i-scan namin ang buong package sa halip na magpahiwatig ng isang partikular na klase na may configuration kapag lumilikha ng konteksto
  • Ang mga pamamaraan ng klase na ito na nagbabalik ng beans ay minarkahan ng @Beananotasyon
  • Kung gusto naming paganahin ang awtomatikong pag-scan kapag gumagamit ng configuration na nakabatay sa Java, ginagamit namin ang @ComponentScananotasyon.
Kung ang artikulong ito ay lubos na nakakalito, pagkatapos ay subukang basahin ito sa loob ng ilang araw. O kung ikaw ay nasa isa sa mga unang antas ng CodeGym, maaaring medyo maaga para sa iyo na mag-aral ng Spring. Maaari kang bumalik sa artikulong ito anumang oras sa ibang pagkakataon kapag mas kumpiyansa ka sa iyong mga kasanayan sa Java programming. Kung malinaw ang lahat, maaari mong subukang i-convert ang ilang pet project mo sa Spring :) Kung ang ilang bagay ay malinaw ngunit ang iba ay hindi, mangyaring mag-iwan ng komento :) Ipaalam sa akin ang iyong mga mungkahi at pintas, kung nagkamali ako somewhere or wrote some nonsense :) Sa susunod na artikulo, sumisid tayo bigla sa spring-web-mvc at gagawa ng simpleng web application gamit ang Spring.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION