JavaRush /Java блогу /Random-KY /Көз карандылык инъекциясына кыска экскурсия же "CDI дагы ...
Viacheslav
Деңгээл

Көз карандылык инъекциясына кыска экскурсия же "CDI дагы эмне?"

Группада жарыяланган
Эң популярдуу алHowтардын негизи азыр көз карандылык инъекциясы болуп саналат. Мен CDI спецификациясында бул жөнүндө эмне дейт, бизде кандай негизги мүмкүнчүлүктөр бар жана аларды кантип колдоно аларыбызды карап чыгууну сунуштайм.
Көз карандылыктын инъекциясына кыскача экскурсия же

Киришүү

Мен бул кыскача баяндаманы CDI сыяктуу нерсеге арнагым келет. Бул эмне? CDI контексттерди жана көз карандылыкты киргизүүнү билдирет. Бул көз карандылык инъекциясын жана контексттерди сүрөттөгөн Java EE спецификациясы. Маалымат үчүн http://cdi-spec.org веб-сайтынан карасаңыз болот . CDI - бул спецификация (анын кантип иштеши керектигинин сүрөттөлүшү, интерфейстердин жыйындысы) болгондуктан, аны колдонуу үчүн бизге ишке ашыруу керек болот. Мындай ишке ашыруулардын бири Weld - http://weld.cdi-spec.org/ Көз карандылыкты башкаруу жана долбоор түзүү үчүн биз Mavenди колдонобуз - https://maven.apache.org Ошентип, бизде Maven орнотулду, эми бизде абстракттуу түшүнбөш үчүн, аны иш жүзүндө түшүнөт. Бул үчүн биз Maven аркылуу долбоор түзөбүз. Келиңиз, буйрук сабын ачалы (Windows'та Win+R баскычтарын колдонуп, "Run" терезесин ачып, cmd аткарсаңыз болот) жана Mavenден биз үчүн бардыгын жасоону сураныңыз. Бул үчүн Maven архетип деп аталган түшүнүккө ээ: Maven Archetype .
Көз карандылыктын инъекциясына кыскача экскурсия же
Андан кийин, “ Сандарды тандаңыз же фильтрди колдонуңуз ” жана “ org.apache.maven.archetypes:maven-archetype-quickstart versionсын тандаңыз ” деген суроолорго жөн гана Enter баскычын басыңыз. Андан кийин, GAV деп аталган долбоордун идентификаторлорун киргизиңиз ( Ат коюу конвенциясы боюнча колдонмону караңыз ).
Көз карандылыктын инъекциясына кыскача экскурсия же
Долбоор ийгorктүү түзүлгөндөн кийин, биз "ИЙГИЛИК КУРУ" деген жазууну көрөбүз. Эми биз өзүбүздүн проектибизди сүйүктүү IDEде ача алабыз.

Долбоорго CDI кошуу

Кириш сөзүндө биз CDIдин кызыктуу веб-сайты бар экенин көрдүк - http://www.cdi-spec.org/ . Жүктөө бөлүмү бар, анда бизге керектүү маалыматтарды камтыган table бар:
Көз карандылыктын инъекциясына кыскача экскурсия же
Бул жерде биз Maven долбоордо CDI API колдонгонубузду кантип сүрөттөп жатканын көрө алабыз. API - бул колдонмо программалоо интерфейси, башкача айтканда, кээ бир программалоо интерфейси. Биз интерфейс менен иштейбиз, бул интерфейстин артында эмне жана кантип иштейт. API бул jar архиви, аны биз долбоордо колдоно баштайбыз, башкача айтканда, биздин долбоор бул банкага көз каранды боло баштайт. Ошондуктан, биздин долбоор үчүн CDI API көз карандылык болуп саналат. Mavenде долбоор POM.xml файлдарында сүрөттөлөт ( POM - Project Object Model ). Көз карандылыктар көз карандылык блогунда сүрөттөлөт, ага биз жаңы жазууну кошуубуз керек:
<dependency>
	<groupId>javax.enterprise</groupId>
	<artifactId>cdi-api</artifactId>
	<version>2.0</version>
</dependency>
Сиз байкагандай, биз берилген маани менен масштабды тактабайбыз. Эмне үчүн мындай айырма бар? Бул масштаб кимдир бирөө бизге көз карандылыкты камсыз кылат дегенди билдирет. Тиркеме Java EE serverинде иштегенде, server тиркемени бардык керектүү JEE технологиялары менен камсыз кылат дегенди билдирет. Бул карап чыгуунун жөнөкөйлүгү үчүн, биз Java SE чөйрөсүндө иштейбиз, ошондуктан эч ким бизге бул көз карандылыкты бербейт. Көз карандылыктын масштабы тууралуу кененирээк бул жерден окуй аласыз: " Көз карандылыктын масштабы ". Макул, бизде интерфейстер менен иштөө мүмкүнчүлүгү бар. Бирок биз ишке ашырууга да муктажбыз. Эсибизде тургандай, биз Weld колдонобуз. Баардык жерде ар кандай көз карандылыктар берorп жатканы кызык. Бирок биз documentацияны аткарабыз. Ошондуктан, келгиле, " 18.4.5. Класстын жолду орнотуу " дегенди окуп, анда айтылгандай кылалы:
<dependency>
	<groupId>org.jboss.weld.se</groupId>
	<artifactId>weld-se-core</artifactId>
	<version>3.0.5.Final</version>
</dependency>
Weld үчүнчү сап versionлары CDI 2.0 колдошу маанилүү. Ошондуктан, биз бул versionнын API'ге ишенсек болот. Эми биз code жазууга даярбыз.
Көз карандылыктын инъекциясына кыскача экскурсия же

CDI контейнерин баштоо

CDI механизми болуп саналат. Бул механизмди кимдир бирөө көзөмөлдөшү керек. Жогоруда айтылгандай, мындай менеджер контейнер болуп саналат. Ошондуктан, биз аны түзүшүбүз керек, ал өзү SE чөйрөсүндө пайда болбойт. Биздин негизги ыкмабызга төмөнкүлөрдү кошолу:
public static void main(String[] args) {
	SeContainerInitializer initializer = SeContainerInitializer.newInstance();
	initializer.addPackages(App.class.getPackage());
	SeContainer container = initializer.initialize();
}
Биз CDI контейнерин кол менен түздүк, анткени... Биз SE чөйрөсүндө иштейбиз. Кадимки согуштук долбоорлордо code serverде иштейт, ал codeду ар кандай технологиялар менен камсыз кылат. Демек, эгер server CDI менен камсыз кылса, бул serverде CDI контейнери бар экенин жана эч нерсе кошуунун кереги жок дегенди билдирет. Бирок бул окуу куралынын максаттары үчүн биз SE чөйрөсүн алабыз. Мындан тышкары, контейнер бул жерде, так жана түшүнүктүү. Эмне үчүн бизге контейнер керек? Ичиндеги идиштин ичинде буурчак (CDI буурчак) бар.
Көз карандылыктын инъекциясына кыскача экскурсия же

CDI буурчак

Ошентип, буурчак. CDI бин деген эмне? Бул кээ бир эрежелерди сактаган Java классы. Бул эрежелер спецификациянын " 2.2. Төө буурчак кандай класстарга кирет? " главасында баяндалган. Колдонмо классы менен бир пакетке CDI буурчакты кошолу:
public class Logger {
    public void print(String message) {
        System.out.println(message);
    }
}
Эми биз бул буурчакты биздин ыкмабыздан чакыра алабыз main:
Logger logger = container.select(Logger.class).get();
logger.print("Hello, World!");
Көрүнүп тургандай, биз төө буурчакты new ачкыч сөзүн колдонуп жараткан жокпуз. Биз CDI контейнеринен сурадык: "CDI контейнери. Мага чындап эле Logger классынын үлгүсү керек, аны мага бериңизчи." Бул ыкма " Көз карандылыкты издөө ", башкача айтканда, көз карандылыктарды издөө деп аталат . Эми жаңы класс түзөлү:
public class DateSource {
    public String getDate() {
        return new Date().toString();
    }
}
Датаны тексттик көрсөтүүнү кайтаруучу примитивдүү класс. Келгиле, эми билдирүүгө датаны кошолу:
public class Logger {
    @Inject
    private DateSource dateSource;

    public void print(String message) {
        System.out.println(dateSource.getDate() + " : " + message);
    }
}
Кызыктуу @Inject annotationсы пайда болду. Cdi ширетүү documentтеринин " 4.1. Инъекция пункттары " бөлүмүндө айтылгандай , бул annotationны колдонуу менен биз Инъекция чекитинин аныктайбыз. Орус тorнде муну "ишке ашыруу пункттары" деп окуса болот. Алар CDI контейнери тарабынан буурчактарды түзүү учурунда көз карандылыкты киргизүү үчүн колдонулат. Көрүнүп тургандай, биз dateSource талаасына эч кандай маани берген жокпуз. Мунун себеби, CDI контейнеринин CDI буурчактарынын ичине (ал өзү жараткан, б.а. өзү башкарган буурчактарды гана) " Көз карандылык инъекциясын " колдонууга уруксат бергендиги. Бул башкаруунун инversionсынын дагы бир жолу , көз карандылык an objectтерди түзүүдө биз эмес, башка бирөө тарабынан башкарылат. Көз карандылыкты киргизүү ыкмасы, конструктор же талаа аркылуу жүргүзүлүшү мүмкүн. Көбүрөөк маалымат алуу үчүн CDI спецификациясынын " 5.5. Көз карандылык инъекциясы " бөлүмүн караңыз. Эмнени ишке ашыруу керек экендигин аныктоо proceduresасы коопсуз резолюция деп аталат, бул жөнүндө биз сүйлөшүшүбүз керек.
Көз карандылыктын инъекциясына кыскача экскурсия же

Аталышынын чечими же Typesafe резолюциясы

Адатта, ишке ашырыла турган an objectтин түрү катары интерфейс колдонулат жана CDI контейнери кайсы ишке ашырууну тандоону өзү аныктайт. Бул биз талкуулай турган көптөгөн себептерден улам пайдалуу. Ошентип, бизде логгер интерфейси бар:
public interface Logger {
    void print(String message);
}
Эгерде бизде бир аз логист болсо, биз ага билдирүү жөнөтө алабыз жана ал өзүнүн тапшырмасын аткарат - лог. Бул учурда кантип жана кайда кызыкдар болбойт. Эми логгер үчүн ишке ашырууну түзөлү:
public class SystemOutLogger implements Logger {
    @Inject
    private DateSource dateSource;

    public void print(String message) {
        System.out.println(message);
    }
}
Көрүнүп тургандай, бул System.out сайтына жазган логгер. Керемет. Эми биздин негизги ыкмабыз мурдагыдай иштей баштайт. Logger logger = container.select(Logger.class).get(); Бул линия дагы эле логист тарабынан кабыл алынат. Ал эми сулуулугу, биз интерфейсти гана бorшибиз керек, жана CDI контейнери биз үчүн ишке ашыруу жөнүндө ойлонот. Бизде журналды алыскы сактагычка жөнөтө турган экинчи ишке ашыруу бар дейли:
public class NetworkLogger implements Logger {
    @Override
    public void print(String message) {
        System.out.println("Send log message to remote log system");
    }
}
Эгерде биз азыр codeубузду өзгөртүүсүз иштетсек, анда ката алабыз, анткени CDI контейнери интерфейстин эки аткарылышын көрөт жана алардын арасынан тандай алbyte: org.jboss.weld.exceptions.AmbiguousResolutionException: WELD-001335: Ambiguous dependencies for type Logger Эмне кылуу керек? жеткorктүү бир нече вариациялар бар. Эң жөнөкөйсү CDI буурчагы үчүн @Vetoed annotationсы , андыктан CDI контейнери бул классты CDI буурчагы катары кабыл алbyte. Бирок алда канча кызыктуу ыкма бар. CDI бурчту Weld CDI documentациясынын " 4.7. Альтернативалар@Alternative " бөлүмүндө сүрөттөлгөн annotationны колдонуу менен "альтернатива" катары белгилениши мүмкүн . Бул эмнени билдирет? Бул аны колдонууну ачык айтпайынча, ал тандалbyte дегенди билдирет. Бул буурчактын альтернативалуу versionсы. Келгиле, NetworkLogger буурчакты @Alternative деп белгилейли жана биз code кайра аткарылып, SystemOutLogger тарабынан колдонулганын көрөбүз. Альтернативаны иштетүү үчүн, бизде beans.xml файлы болушу керек . Суроо туулат: " beans.xml, мен сени кайда коём? " Ошондуктан, файлды туура жайгаштыралы:
Көз карандылыктын инъекциясына кыскача экскурсия же
Бизде бул файл болгондон кийин, биздин code менен артефакт " Ачык буурчак архиви " деп аталат. Эми бизде 2 өзүнчө конфигурация бар: программалык камсыздоо жана xml. Маселе, алар ошол эле маалыматтарды жүктөй турганында. Мисалы, DataSource буурчак аныктамасы 2 жолу жүктөлөт жана биздин программа аткарылганда бузулат, анткени CDI контейнери аларды 2 өзүнчө буурчак деп эсептейт (чындыгында алар CDI контейнери эки жолу билген бир класс болсо да). Мунун алдын алуу үчүн 2 вариант бар:
  • сызыкты алып салуу initializer.addPackages(App.class.getPackage())жана xml файлына альтернатива белгисин кошуу:
<beans
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://xmlns.jcp.org/xml/ns/javaee
        http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">
    <alternatives>
        <class>ru.javarush.NetworkLogger</class>
    </alternatives>
</beans>
  • буурчактын тамыр элементине " жокbean-discovery-mode " мааниси бар атрибут кошуп , программалык түрдө альтернативаны көрсөтүңүз:
initializer.addPackages(App.class.getPackage());
initializer.selectAlternatives(NetworkLogger.class);
Ошентип, CDI альтернативасын колдонуп, контейнер кайсы буурчакты тандоону аныктай алат. Кызыгы, эгерде CDI контейнери бир эле интерфейс үчүн бир нече альтернативаларды билсе, анда биз annotationны колдонуу менен артыкчылыкты көрсөтүү менен айта алабыз @Priority(CDI 1.1ден бери).
Көз карандылыктын инъекциясына кыскача экскурсия же

Квалификациялар

Өзүнчө, квалификациялар сыяктуу нерсени талкуулоо керек. Квалификация төө буурчактын үстүндө annotation менен көрсөтүлүп, буурчакты издөөнү тактайт. Ал эми азыр кененирээк маалымат. Кызыктуусу, кандай гана болбосун CDI төө буурчактын жок дегенде бир квалификациясы бар - @Any. Эгерде биз буурчактын үстүндө КАНДАЙ Квалифификаторду көрсөтпөсөк, бирок анда CDI контейнеринин өзү @Anyквалификациялоочуга башка квалификаторду кошот - @Default. Эгер биз кандайдыр бир нерсени көрсөтсөк (мисалы, @Any дегенди ачык көрсөтүңүз), анда @Default квалификатору автоматтык түрдө кошулbyte. Бирок квалификациялардын кооздугу - сиз өзүңүздүн квалификацияңызды жасай аласыз. Квалификация annotationлардан дээрлик айырмаланbyte, анткени негизи, бул жөн гана өзгөчө түрдө жазылган annotation. Мисалы, сиз протокол түрү үчүн Enum киргизе аласыз:
public enum ProtocolType {
    HTTP, HTTPS
}
Андан кийин биз бул түрдү эске ала турган квалификацияны түзө алабыз:
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Protocol {
    ProtocolType value();
    @Nonbinding String comment() default "";
}
@NonbindingБелгиленген талаалар квалификацияны аныктоого таасир этпей турганын белгилей кетүү керек . Эми сиз квалификацияны көрсөтүшүңүз керек. Ал буурчактын түрүнүн үстүндө (CDI аны кантип аныктоону бorши үчүн) жана Инъекция чекитинин үстүндө (@Inject annotationсы менен) көрсөтүлгөн, андыктан сиз бул жерде инъекция үчүн кайсы буурчакты издөө керектигин түшүнөсүз. Мисалы, биз квалификациялуу класстарды кошо алабыз. Жөнөкөйлүк үчүн, бул макалада биз аларды NetworkLogger ичинде жасайбыз:
public interface Sender {
	void send(byte[] data);
}

@Protocol(ProtocolType.HTTP)
public static class HTTPSender implements Sender{
	public void send(byte[] data) {
		System.out.println("sended via HTTP");
	}
}

@Protocol(ProtocolType.HTTPS)
public static class HTTPSSender implements Sender{
	public void send(byte[] data) {
		System.out.println("sended via HTTPS");
	}
}
Анан биз Inject аткарганда, кайсы класс колдонула турганына таасир эте турган квалификаторду көрсөтөбүз:
@Inject
@Protocol(ProtocolType.HTTPS)
private Sender sender;
Сонун, туурабы?) Бул сулуу көрүнөт, бирок эмне үчүн экени түшүнүксүз. Эми төмөндөгүлөрдү элестетиңиз:
Protocol protocol = new Protocol() {
	@Override
	public Class<? extends Annotation> annotationType() {
		return Protocol.class;
	}
	@Override
	public ProtocolType value() {
		String value = "HTTP";
		return ProtocolType.valueOf(value);
	}
};
container.select(NetworkLogger.Sender.class, protocol).get().send(null);
Ушундай жол менен биз динамикалык түрдө эсептелген маанини жокко чыгара алабыз. Мисалы, кээ бир орнотуулардан алынышы мүмкүн. Андан кийин биз программаны/serverди кайра компиляциялоосуз же кайра иштетпестен эле ишке ашырууну өзгөртө алабыз. Бул алда канча кызыктуу болот, туурабы? )
Көз карандылыктын инъекциясына кыскача экскурсия же

Продюсерлор

CDI дагы бир пайдалуу өзгөчөлүгү өндүрүүчүлөр болуп саналат. Бул кээ бир буурчак көз карандылык инъекциясын суранганда чакырылган атайын ыкмалар (алар атайын annotation менен белгиленет). Толук маалымат documentациянын " 2.2.3. Өндүрүүчүнүн ыкмалары " бөлүмүндө баяндалат. Эң жөнөкөй мисал:
@Produces
public Integer getRandomNumber() {
	return new Random().nextInt(100);
}
Эми, Integer түрүндөгү талааларга инъекциялоодо, бул ыкма чакырылып, андан маани алынат. Бул жерде биз жаңы ачкыч сөзүн көргөндө, бул CDI буурчагы ЭМЕС экенин дароо түшүнүшүбүз керек. Башкача айтканда, Random классынын мисалы CDI контейнерин башкарган нерседен (бул учурда продюсерден) алынганы үчүн эле CDI буурчагы болуп калbyte.
Көз карандылыктын инъекциясына кыскача экскурсия же

Чектөөчүлөр

Интерцепторлор — ишке «тоскоолдук кылуучу» тосмолор. CDI бул абдан ачык-айкын жасалган. Келгиле, котормочуларды (же тосмолорду) колдонуу менен кантип журнал жазууга болорун карап көрөлү. Биринчиден, биз интерцептор менен байланышты сүрөттөшүбүз керек. Көп нерселер сыяктуу эле, бул annotationларды колдонуу менен ишке ашырылат:
@Inherited
@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface ConsoleLog {
}
Бул жерде негизги нерсе, бул @InterceptorBindingкеңейтүү ( ) тарабынан тукум куу боло турган интерцептор ( ) үчүн милдеттүү болуп саналат @InterceptorBinding. Эми интерцептордун өзүн жазалы:
@Interceptor
@ConsoleLog
public class LogInterceptor {
    @AroundInvoke
    public Object log(InvocationContext ic) throws Exception {
        System.out.println("Invocation method: " + ic.getMethod().getName());
        return ic.proceed();
    }
}
Мисалда интерцепторлор кантип жазылганы тууралуу кененирээк спецификациядан окуй аласыз: " 1.3.6. Interceptor мисалы ". Болгону биз инерцепторду күйгүзүшүбүз керек. Бул үчүн, аткарылып жаткан ыкманын үстүндө милдеттүү annotationны көрсөтүңүз:
@ConsoleLog
public void print(String message) {
Ал эми азыр дагы бир абдан маанилүү майда-чүйдөсүнө чейин. Чектөөчүлөр демейки боюнча өчүрүлгөн жана альтернативалар сыяктуу эле иштетorши керек. Мисалы, beans.xml файлында :
<interceptors>
	<class>ru.javarush.LogInterceptor</class>
</interceptors>
Көрүнүп тургандай, бул абдан жөнөкөй.
Көз карандылыктын инъекциясына кыскача экскурсия же

Окуя жана байкоочулар

CDI ошондой эле окуялардын жана байкоочулардын моделин камсыз кылат. Бул жерде бардыгы тоскучтардагыдай айкын эмес. Ошентип, бул учурда Окуя таптакыр кандайдыр бир класс болушу мүмкүн; сүрөттөмө үчүн өзгөчө эч нерсе талап кылынbyte. Мисалы:
public class LogEvent {
    Date date = new Date();
    public String getDate() {
        return date.toString();
    }
}
Эми кимдир бирөө окуяны күтүшү керек:
public class LogEventListener {
    public void logEvent(@Observes LogEvent event){
        System.out.println("Message Date: " + event.getDate());
    }
}
Бул жерде эң негизгиси @Observes annotationсын көрсөтүү, бул жөн гана метод эмес, LogEvent тибиндеги окуяларга байкоо жүргүзүүнүн натыйжасында чакырылышы керек болгон метод. Эми бизге карап турган бирөө керек:
public class LogObserver {
    @Inject
    private Event<LogEvent> event;
    public void observe(LogEvent logEvent) {
        event.fire(logEvent);
    }
}
Бизде бир гана ыкма бар, ал контейнерге LogEvent окуя түрү үчүн Окуя окуясы болгонун айтып берет. Эми байкоочуну колдонуу гана калды. Мисалы, NetworkLoggerде биз байкоочубуздун инъекциясын кошо алабыз:
@Inject
private LogObserver observer;
Ал эми басып чыгаруу ыкмасы менен биз байкоочуга жаңы окуя бар экенин билдире алабыз:
public void print(String message) {
	observer.observe(new LogEvent());
Окуяларды бир жипте же бир нече иретте иштетүүгө болоорун билүү маанилүү. Асинхрондук иштетүү үчүн методду .fireAsync(.fire ордуна) жана annotationны @ObservesAsync(@Observes ордуна) колдонуңуз. Мисалы, бардык окуялар ар кандай жиптерде аткарылса, анда 1 жип Exception ыргытса, анда калгандары башка окуялар үчүн өз ишин аткара алышат. Сиз CDIдеги окуялар тууралуу кененирээк, адаттагыдай, спецификациянын " 10. Окуялар " бөлүмүнөн окуй аласыз .
Көз карандылыктын инъекциясына кыскача экскурсия же

Декораторлор

Жогоруда көргөнүбүздөй, ар кандай дизайн үлгүлөрү CDI канатынын астында чогултулган. Ал эми бул жерде дагы бир - жасалгалоочу. Бул абдан кызыктуу нерсе. Келгиле, бул классты карап көрөлү:
@Decorator
public abstract class LoggerDecorator implements Logger {
    public final static String ANSI_GREEN = "\u001B[32m";
    public static final String ANSI_RESET = "\u001B[0m";

    @Inject
    @Delegate
    private Logger delegate;

    @Override
    public void print(String message) {
        delegate.print(ANSI_GREEN + message + ANSI_RESET);
    }
}
Аны жасалгалоочу деп жарыялоо менен, биз каалаган Logger ишке ашыруу колдонулганда, делегат талаасында сакталган чыныгы ишке ашырууну билген бул “кошумча” колдонулат деп айтабыз (annotation менен белгиленген ) @Delegate. Декораторлорду CDI буурчак менен гана байланыштырса болот, ал өзү тосуучу да, жасалгалоочу да эмес. Мисалды спецификациядан да көрүүгө болот: " 1.3.7. Декоратордун мисалы ". Декоратор, тосуучу сыяктуу, күйгүзүлүшү керек. Мисалы, beans.xml ичинде :
<decorators>
	<class>ru.javarush.LoggerDecorator</class>
</decorators>
Көбүрөөк маалымат алуу үчүн, ширетүүчү шилтемени караңыз: " 10-бөлүм. Декораторлор ".

Жашоо цикл

Төө буурчактын өзүнүн жашоо цикли бар. Бул мындай көрүнөт:
Көз карандылыктын инъекциясына кыскача экскурсия же
Сүрөттөн көрүнүп тургандай, бизде жашоо циклинин кайра чалуулары бар. Бул annotationлар, алар CDI контейнерине буурчактын жашоо циклинин белгилүү бир этабында белгилүү ыкмаларды чакырууга жардам берет. Мисалы:
@PostConstruct
public void init() {
	System.out.println("Inited");
}
Бул ыкма CDI буурчагы контейнер тарабынан түзүлгөндө чакырылат. Ошол эле @PreDestroy менен төө буурчактын кереги жок болгондо жок кылынганда болот. CDI аббревиатурасында C тамгасы бар экендиги бекеринен эмес - Контекст. CDIдеги буурчактар ​​контексттик болуп саналат, башкача айтканда, алардын жашоо цикли CDI контейнеринин ичиндеги контексттен көз каранды. Муну жакшыраак түшүнүү үчүн " 7. Контексттик инстанциялардын жашоо цикли " спецификация бөлүмүн окушуңуз керек . Контейнердин өзүнүн жашоо цикли бар экенин да билүү керек, бул тууралуу сиз " Контейнердин жашоо циклинин окуялары " бөлүмүнөн окуй аласыз.
Көз карандылыктын инъекциясына кыскача экскурсия же

Бардыгы

Жогоруда биз CDI деп аталган айсбергдин эң четин карадык. CDI JEE спецификациясынын бир бөлүгү жана JavaEE чөйрөсүндө колдонулат. Жазды колдонгондор CDI эмес, DI колдонушат, башкача айтканда, булар бир аз башкача спецификациялар. Бирок жогоруда айтылгандарды бorп, түшүнүү менен сиз оюңузду оңой эле өзгөртө аласыз. Жаздын CDI дүйнөсүндөгү annotationларды колдой тургандыгын эске алуу менен (ошол эле Inject). Кошумча материалдар: #Вячеслав
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION