JavaRush /Java блогу /Random-KY /Жаз жалкоолорго. Негиздери, негизги түшүнүктөр жана код м...
Стас Пасинков
Деңгээл
Киев

Жаз жалкоолорго. Негиздери, негизги түшүнүктөр жана код менен мисалдар. 2 бөлүк

Группада жарыяланган
Акыркы макалада мен кыскача жаз деген эмне экенин, урналар жана контекстти түшүндүрүп бердим. Эми мунун баары кантип иштээрин сынап көрүүгө убакыт келди. Жаз жалкоолорго.  Негиздери, негизги түшүнүктөр жана code менен мисалдар.  2-1-бөлүкМен муну Intellij Idea Enterprise Edition менен өзүм жасайм. Бирок менин бардык мисалдарым бекер Intellij Idea Community Edition менен иштеши керек. Скриншоттордон менде сизде жок терезе бар экенин көрсөңүз, кабатыр болбоңуз, бул долбоор үчүн маанилүү эмес :) Биринчиден, бош Maven долбоорун түзөлү. Мен макалада муну кантип жасоону көрсөттү (" Мавен долбоорубузду веб-долбоорго айлантууга убакыт келди. " деген сөздөрдү окуганга чейин окуңуз , андан кийин ал веб-долбоорду кантип түзүү керектигин көрсөтүп турат жана бизге азыр мунун кереги жок) Келгиле, аны src/main папкасында түзөлү /java бул кандайдыр бир пакет (менин учурда мен аны “ ru.javarush.info.fatfaggy.animals” деп атадым, аны каалагандай атай аласыз, жөн гана керектүү жерлерге атыңыз менен алмаштырууну унутпаңыз). MainЖана биз метод жасай турган класс түзөлү
public static void main(String[] args) {
    ...
}
Андан кийин pom.xml файлын ачып, ал жерге бөлүмдү кошуңуз dependencies. Эми биз Maven репозиторийине барып , ал жерден эң акыркы туруктуу versionнын жазгы контекстти издеп , бөлүмдүн ичине алганыбызды чаптайбыз dependencies. Мен бул процессти ушул макалада бир аз майда-чүйдөсүнө чейин сүрөттөп бердим (" Mavenдеги көз карандылыктарды кошуу " бөлүмүн караңыз ). Андан кийин Maven өзү керектүү көз карандылыктарды таап, жүктөп алат жана аягында сиз төмөнкүдөй нерсени алышыңыз керек:
Жаз жалкоолорго.  Негиздери, негизги түшүнүктөр жана code менен мисалдар.  2-2-бөлүк
Сол терезеде пакет жана класс менен долбоордун түзүмүн көрө аласыз Main. Ортоңку терезе менин pom.xml кандай экенин көрсөтөт. Мен ошондой эле ал жерде касиеттер бөлүмүн коштум , анда мен Mavenге Java-нын кайсы versionсын баштапкы codeдо колдонуп жатканымды жана кайсы versionны компиляциялоону көрсөттүм. Бул жөн гана Javaнын эски versionсы колдонулуп жаткандыгы жөнүндө эскертүү идеясын түшүнбөшүм үчүн. Сиз жасай аласыз, кыла албайсыз) Оң терезеде - биз жазгы контекстти гана туташтырганыбызга карабастан, ал автоматтык түрдө өзөк, буурчак, aop жана экспрессияны кошконун көрө аласыз. Ар бир модулду өз-өзүнчө туташтырууга мүмкүн болгон, эстутумда ар бири үчүн көз карандылыкты versionнын ачык-айкын көрсөтүүсү менен каттаган, бирок биз азыркыдай вариантка ыраазыбыз. Эми пакетти entities(an objectтерди) түзүп, анда 3 класс түзөлү: Cat, Dog, Parrot. Ар бир жаныбардын аты болсун ( private String name, ал жерде кээ бир баалуулуктарды катуу codeдосоңуз болот), алуучулар/жөндөөчүлөр жалпыга ачык. Эми класска барып 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());
}
Биринчиден, биз контексттик an objectти түзөбүз жана конструктордо ага буурчактын бар-жогуна сканерден өтүшү керек болгон пакеттин атын беребиз. Башкача айтканда, Жаз бул пакеттен өтүп, Жаз бул буурчак экенин билүүгө мүмкүндүк берген атайын annotationлар менен белгиленген класстарды табууга аракет кылат. Андан кийин ал бул класстардын an objectтерин түзүп, аларды контекстке жайгаштырат. Андан кийин биз бул контексттен мышык алабыз. Контексттик an objectке кайрылууда биз андан бизге фасоль (an object) берүүнү суранабыз жана бизге an objectтин кайсы классы керек экенин көрсөтөбүз (бул жерде, демек, класстарды гана эмес, интерфейстерди да көрсөтүүгө болот). Андан кийин Spring бизге ушул класстын an objectисин кайтарып берет, биз аны өзгөрмөгө сактайбыз. Андан кийин Жаздан бизге "ит" деген төө буурчакты алып берүүсүн суранабыз. Spring класс an objectисин жаратканда, Dogага стандарттуу ат берет (эгерде түзүлүп жаткан буурчактын аты ачык көрсөтүлбөсө), бул an objectтин классынын аталышы, кичинекей тамга менен гана. Ошондуктан, биздин класс , деп аталгандыктан Dog, мындай төө буурчактын аты "ит" болот. Эгерде бизде an object болсо BufferedReader, анда Жаз ага демейки "bufferedReader" аталышын бермек. Жана бул учурда (Javaда) мындай an object кандай класс болоруна так ишеним жок болгондуктан, ал жөн гана белгилүү бир an objectти кайтарып берет Object, аны биз кол менен керектүү түргө чыгарабыз Dog. Класстын ачык көрсөтүлгөн варианты ыңгайлуураак. Ооба, үчүнчү учурда, биз класс жана аты боюнча буурчак алабыз. Жөн эле жагдай болушу мүмкүн, контекстте бир класстын бир нече буурчактары болот жана бизге кайсы буурчак керек экенин көрсөтүү үчүн анын атын көрсөтөбүз. Биз бул жерде классты да так көрсөткөндүктөн, мындан ары кастингдин кереги жок. Маанилүү!Эгерде жаз биз белгилеген талаптарга ылайык бир нече төө буурчак таап чыкса, ал бизге кайсы төө буурчакты берерин аныктай албай, өзгөчө абалга алып келет. Ошондуктан, мындай жагдайлар пайда болбошу үчүн, ага мүмкүн болушунча так көрсөтүүгө аракет кылыңыз. Эгерде Жаз сиздин шарттарыңызга ылайык контекстте бир даана төө буурчакты таппаса, анда ал да өзгөчөлүктү жаратат. Анда биз жөн гана жаныбарларыбыздын атын экранга көрсөтөбүз, булар чындыгында бизге керектүү an objectтер экенине ынануу. Бирок программаны азыр ишке ашырсак, Жаз өз контекстинде бизге керектүү жаныбарларды таба албай ант берип жатканын көрөбүз. Бул төө буурчактарды ал жаратпагандыктан болду. Жогоруда айткандай, Жаз класстарды сканерлегенде, ал жерден "өзүнүн" Жазгы annotationларын издейт. Ал эми аны таппаса, анда ал төө буурчак түзүшү керек болгон класстарды кабыл алbyte. @ComponentМуну оңдоо үчүн, биздин жаныбарлар класстарындагы класстын алдына annotation кошуңуз .
@Component
public class Cat {
	private String name = "Barsik";
	...
}
Бирок бул баары эмес. Бул класс үчүн буурчактын белгилүү бир аталышы болушу керек экенин Жазга ачык көрсөтүү керек болсо, анда бул ат annotationдан кийин кашаанын ичинде көрсөтүлүшү мүмкүн. parrot-keshaМисалы, Жаз бул тоту кушту кийинчерээк ала турган төө буурчакка атын бериш үчүн main, биз төмөнкүдөй иш кылышыбыз керек:
@Component("parrot-kesha")
public class Parrot {
	private String name = "Kesha";
	...
}
Бул автоматтык конфигурациянын бардык пункту . Сиз класстарыңызды жазасыз, аларды керектүү annotationлар менен белгилейсиз жана Springке класстарыңыз менен пакетти көрсөтөсүз, ал аркылуу ал annotationларды издеп, мындай класстардын an objectтерин түзөт. Баса, Жаз бир гана annotationларды эмес @Component, мындан башка бардык annotationларды да издейт. Мисалы, @Controller, @RestController, @Service, @Repositoryжана башкалар, алар менен кийинки макалаларда таанышабыз. Эми ошону кылганга аракет кылалы, бирок java конфигурациясын колдонуп . @ComponentБиринчиден, класстарыбыздан annotationларды алып салалы . Тапшырманы татаалдаштыруу үчүн, келгиле, бул биздин өз алдынча жазылган класстар эмес деп элестетип көрөлү, биз аларды оңой эле өзгөртүп, бир нерсени, анын ичинде annotationларды кошо алабыз. Бул класстар кандайдыр бир китепканада жыйылгандай. Бул учурда, биз бул класстарды жазга чейин кабыл алуу үчүн эч кандай түрдө түзөтө албайбыз. Бирок бизге бул класстардын an objectилери керек! Бул жерде бизге мындай an objectтерди түзүү үчүн java конфигурациясы керек болот. Баштоо үчүн, пакетти түзөлү, мисалы configs, жана анын ичинде - мисалы, кадимки Java классы MyConfigжана аны annotation менен белгилейли.@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");
Бул учурда, Жаз бул пакеттен өтүп, annotation менен белгиленген бардык класстарды табат @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 annotation менен белгиленген класстарды издейт @Configurationжана бул класстардын an objectтерин өзү түзөт. Андан кийин ал annotation менен белгиленген бул класстардагы методдорду чакырганга аракет кылат @Bean, бул мындай ыкмалар анын контекстинде мурунтан эле жайгаштырган буурчактарды (an objectтерди) кайтарып берет дегенди билдирет. Келгиле, азыр классыбызда java конфигурациясы менен мышык, ит жана тоту куш буурчактарды түзөлү. Бул абдан жөнөкөй жасалат:
@Bean
public Cat getCat() {
	return new Cat();
}
Көрсө, мышыгыбызды өзүбүз кол менен жаратып, Жазга бергенбиз, ал биздин бул an objectибизди өзүнүн контекстинде жайгаштырып койгон экен. Төө буурчакыбыздын атын ачык тактабагандыктан, Жаз төө буурчакка ыкманын аты менен бирдей ат берет. Биздин учурда, мышыктын буурчагы " getCat" аталышына ээ болот. Бирок -e ичинде mainбиз мышыктын аты менен эмес, классы боюнча алабыз, анда бул учурда бул бинанын аты биз үчүн маанилүү эмес. Ушундай эле ыкма менен ит менен төө буурчакты жасаңыз, бирок Жаз мындай төө буурчакты ыкманын аты менен атаарын унутпаңыз. Биздин төө буурчакты тоту куш менен ачык аташ үчүн, annotationдан кийин кашаанын ичинде анын атын көрсөтүңүз @Bean:
@Bean("parrot-kesha")
public Object weNeedMoreParrots() {
	return new Parrot();
}
Көрүнүп тургандай, бул жерде мен кайтарылган маанинин түрүн көрсөтүп Object, методду эч нерсе деп атадым. Бул төө буурчактын атына эч кандай таасир этпейт, анткени биз аны бул жерде так койгонбуз. Бирок кайтаруу маанисинин түрүн жана методдун аталышын ачык эмес, аздыр-көптүр так көрсөтүү жакшы. Жөн гана өзүң үчүн, бир жылдан кийин бул долбоорду ачканда. :) Эми бир төө буурчакты түзүү үчүн башка төө буурчакты колдонуу керек болгон жагдайды карап көрөлү . Мисалы, мышыктын фасольиндеги мышыктын аты тоту куштун атынан жана "-киллер" сабынан турушун каалайбыз. Көйгөй жок!
@Bean
public Cat getCat(Parrot parrot) {
	Cat cat = new Cat();
	cat.setName(parrot.getName() + "-killer");
	return cat;
}
Бул жерде Жаз бул төө буурчакты жаратаардан мурун, буга чейин эле түзүлгөн тоту куштун төө буурчагын бул жерге өткөрүп бериши керек экенин көрөт. Ошондуктан, ал тоту кушту түзүү ыкмасы адегенде чакырылышы үчүн, биздин ыкмаларыбызга чалуулардын чынжырын курат, андан кийин бул тоту кушту мышык түзүү ыкмасына өткөрөт. Бул жерде көз карандылык инъекциясы деген нерсе иштеди : Жаздын өзү талап кылынган тоту куштун буурчакты биздин ыкмага өткөрүп берди. Эгерде идея өзгөрмөгө нааразы болсо , тоту кушту parrotтүзүү ыкмасын кайтаруу түрүн өзгөртүүнү унутпаңыз . Мындан тышкары, Java конфигурациясы буурчактарды түзүү ыкмаларында каалаган Java codeун аткарууга мүмкүндүк берет . Сиз чындап эле бардыгын жасай аласыз: башка көмөкчү an objectтерди түзүңүз, башка ыкмаларды чакырыңыз, жада калса жазгы annotationлар менен белгиленбегендерди да чакырыңыз, илмектерди, шарттарды жасаңыз - оюңузга эмне келсе! Мунун бардыгына автоматтык конфигурацияны колдонуу менен жетишүү мүмкүн эмес, xml конфигурацияларын колдонуу азыраак. ObjectParrot Эми кызыктуураак маселени карап көрөлү. Полиморфизм жана интерфейстер менен :) Келгиле, интерфейс түзүп WeekDay, бул интерфейсти ишке ашыра турган 7 класс түзөлү: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. Келгиле, интерфейсте String getWeekDayName()тиешелүү класстын жума күнүнүн атын кайтара турган методду түзөлү. Башкача айтканда, класс Mondayкайтып келет " monday", ж.б. Келгиле, биздин тиркемени ишке киргизүүдө милдет жуманын учурдагы күнүнө туура келген контекстке буурчакты жайгаштыруу болуп саналат деп коёлу. Интерфейсти ишке ашырган бардык класстардын бардык буурчактары эмес 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();
	}
}
Бул жерде кайтарылган маанинин түрү биздин интерфейсибиз жана метод жуманын учурдагы күнүнө жараша интерфейсти ишке ашыруу класстарынын реалдуу an objectтерин кайтарат. Эми методдо main()биз муну жасай алабыз:
WeekDay weekDay = context.getBean(WeekDay.class);
System.out.println("It's " + weekDay.getWeekDayName() + " today!");
Ал мага бүгүн жекшемби экенин айтты :) Мен эртең программаны иштетсем, контекстте таптакыр башка an object пайда болот деп ишенем. Көңүл буруңуз, бул жерде биз төө буурчакты интерфейс аркылуу гана алабыз: context.getBean(WeekDay.class). Жаз өзүнүн контекстине карап, анын кайсы буурчактары ушундай интерфейсти ишке ашырарын жана аны кайтарып берерин көрөт. WeekDayОоба, анда type өзгөрмөсүндө типтин an objectи бар экени көрүнүп турат Sundayжана бул өзгөрмө менен иштөөдө баарыбызга тааныш полиморфизм башталат. :) Жана комбинирленген ыкма жөнүндө бир нече сөз , мында төө буурчактардын бир бөлүгү Жаздын өзү тарабынан, annotationсы бар класстардын бар-жоктугу үчүн пакеттерди сканерлөөнүн жардамы менен түзүлөт @Component, ал эми башка буурчак java конфигурациясынын жардамы менен түзүлөт. Бул үчүн, келгиле , класстар жана annotation менен белгиленген баштапкы versionсына Catкайтып баралы . Жазга чейин таңгактарды автоматтык сканерлөө аркылуу жаныбарларыбыз үчүн урналарды түзгүбүз келет дейли , бирок биз жаңы эле жасагандай, жуманын күнү менен урна түзөлү. Сизге керек болгон нерсе - класстын деңгээлине кошуу , аны --чу annotationда контекстти түзүүдө аныктайбыз жана кашаанын ичинде сканерден өтүшү керек болгон пакетти жана автоматтык түрдө түзүлгөн керектүү класстардын буурчактарын көрсөтүңүз: DogParrot@ComponententitiesMyConfigmain@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();
		}
	}
}
Көрсө, Жаз контекстти түзүп жатканда классты иштетүү керек экенин көрөт MyConfig. Ал ага кирип, " " топтомун сканерлеп, ошол класстардын төө буурчактарын түзүшү керек экенин көрөт , андан кийин класстын ru.javarush.info.fatfaggy.animals.entitiesметодун аткарып , контекстке түрдөгү буурчакты кошот . ыкма, биз азыр бардык керектөө буурчак мүмкүнчүлүгүнө ээ: жаныбарлардын an objectилери жана жума буурчак күнү да. Жаз дагы кээ бир xml конфигурацияларын тандап алганына кантип ынануу керек - эгер сизге керек болсо, Google аны Интернеттен өзүңүз издеңиз :) Кыскача маалымат:getDay()MyConfigWeekDaymain()
  • автоматтык конфигурацияны колдонууга аракет кылуу;
  • автоматтык конфигурациялоодо фасоль түзүлүшү керек болгон класстарды камтыган пакеттин атын көрсөтөбүз;
  • мындай класстар annotation менен белгиленет@Component;
  • жаз ушундай класстардын баарын басып өтүп, алардын an objectилерин жаратып, контекстке жайгаштырат;
  • кандайдыр бир себептерден улам автоматтык конфигурация бизге туура келбесе, биз java конфигурациясын колдонобуз;
  • бул учурда биз кадимки Java классын түзөбүз, анын методдору бизге керектүү an objectтерди кайтарып берет жана @Configurationконтекстти түзүүдө конфигурациялуу конкреттүү классты көрсөтпөстөн, бүт пакетти сканерлеген учурда annotation менен мындай классты белгилейбиз;
  • буурчакты кайтарган бул класстын ыкмалары annotation менен белгиленет @Bean;
  • java конфигурациясын колдонууда автоматтык сканерлөөнү иштетүүнү кааласак, annotationны колдонобуз @ComponentScan.
Эгер эч нерсе түшүнүксүз болсо, анда бул макаланы бир нече күндүн ичинде окуп көрүңүз. Ооба, же эгер сиз Джараштын алгачкы деңгээлинде болсоңуз, анда жазды үйрөнүүгө бир аз эртедир. Сиз Java программасында өзүңүздү ишенимдүү сезгениңизде, бул макалага бир аздан кийин кайрыла аласыз. Эгер баары түшүнүктүү болсо, сиз өзүңүздүн үй жаныбарларыңыздын кээ бир долбоорлорун Жазга которууга аракет кылсаңыз болот :) Эгер бир нерсе түшүнүктүү болсо, бирок анчалык деле көп эмес болсо, комментарий калтырыңыз :) Мен бир жерге басып кетсем же келесоо нерсе жазсам, сунуштар жана комментарийлер бар. ) Кийинки макалада биз spring-web-mvcге терең сүңгүп киребиз жана жазды колдонуу менен жөнөкөй веб тиркемени жасайбыз.
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION