JavaRush /Java Blogu /Random-AZ /Asılılıq inyeksiyasına qısa ekskursiya və ya "CDI başqa n...
Viacheslav
Səviyyə

Asılılıq inyeksiyasına qısa ekskursiya və ya "CDI başqa nədir?"

Qrupda dərc edilmişdir
İndi ən populyar çərçivələrin qurulduğu təməl asılılıq inyeksiyasıdır. Mən CDI spesifikasiyasının bu barədə nə dediyini, hansı əsas imkanlara malik olduğumuzu və onlardan necə istifadə edə biləcəyimizi nəzərdən keçirməyi təklif edirəm.
Asılılıq inyeksiyasına qısa ekskursiya və ya

Giriş

Bu qısa icmalı CDI kimi bir şeyə həsr etmək istərdim. Bu nədir? CDI kontekstlər və asılılıq inyeksiyası deməkdir. Bu, Dependency Injection və kontekstləri təsvir edən Java EE spesifikasiyasıdır. Məlumat üçün http://cdi-spec.org saytına baxa bilərsiniz . CDI spesifikasiya olduğundan (onun necə işləməli olduğunun təsviri, bir sıra interfeyslər), ondan istifadə etmək üçün bizə də bir tətbiq lazımdır. Belə tətbiqlərdən biri Weld-dir - http://weld.cdi-spec.org/ Asılılıqları idarə etmək və layihə yaratmaq üçün biz Maven istifadə edəcəyik - https://maven.apache.org Beləliklə, biz Maven quraşdırdıq, indi biz mücərrəd başa düşməmək üçün onu praktikada başa düşəcək. Bunun üçün Maven-dən istifadə edərək layihə yaradacağıq. Gəlin komanda xəttini açaq (Windows-da Win+R düymələrindən istifadə edərək “Run” pəncərəsini açıb cmd-ni icra edə bilərsiniz) və Mavendən bizim üçün hər şeyi etməsini xahiş edək. Bunun üçün Mavenin arxetip adlı bir konsepsiyası var: Maven Arxetipi .
Asılılıq inyeksiyasına qısa ekskursiya və ya
Bundan sonra “ Nömrə seçin və ya filtr tətbiq edin ” və “ org.apache.maven.archetypes:maven-archetype-quickstart versiyasını seçin ” suallarına sadəcə Enter düyməsini basın. Sonra, GAV adlanan layihə identifikatorlarını daxil edin (bax: Adlandırma Konvensiyası Bələdçisi ).
Asılılıq inyeksiyasına qısa ekskursiya və ya
Layihənin uğurlu yaradılmasından sonra biz “UĞUR QURU” yazısını görəcəyik. İndi layihəmizi sevimli IDE-də aça bilərik.

Layihəyə CDI əlavə edilməsi

Girişdə CDI-nin maraqlı bir internet saytının olduğunu gördük - http://www.cdi-spec.org/ . Bizə lazım olan məlumatları ehtiva edən bir cədvəl olan bir yükləmə bölməsi var:
Asılılıq inyeksiyasına qısa ekskursiya və ya
Burada Maven-in layihədə CDI API istifadə etdiyimizi necə təsvir etdiyini görə bilərik. API tətbiqi proqramlaşdırma interfeysidir, yəni bəzi proqramlaşdırma interfeysidir. Biz bu interfeysin arxasında nə və necə işlədiyindən narahat olmadan interfeyslə işləyirik. API layihəmizdə istifadə etməyə başlayacağımız jar arxividir, yəni layihəmiz bu jardan asılı olmağa başlayır. Buna görə də, layihəmiz üçün CDI API bir asılılıqdır. Maven-də layihə POM.xml fayllarında təsvir olunur ( POM - Layihə Obyekt Modeli ). Asılılıqlar asılılıqlar blokunda təsvir edilmişdir, ona yeni giriş əlavə etməliyik:
<dependency>
	<groupId>javax.enterprise</groupId>
	<artifactId>cdi-api</artifactId>
	<version>2.0</version>
</dependency>
Diqqət etdiyiniz kimi, verilən dəyərlə əhatə dairəsini göstərmirik. Niyə belə bir fərq var? Bu əhatə dairəsi o deməkdir ki, kimsə bizi asılılıq ilə təmin edəcək. Tətbiq Java EE serverində işlədikdə, bu o deməkdir ki, server tətbiqi bütün lazımi JEE texnologiyaları ilə təmin edəcək. Bu baxışın sadəliyi naminə biz Java SE mühitində işləyəcəyik, ona görə də heç kim bizə bu asılılığı təmin etməyəcək. Dependency Scope haqqında burada oxuya bilərsiniz: " Dependency Scope ". Yaxşı, indi interfeyslərlə işləmək imkanımız var. Amma bizim də icraya ehtiyacımız var. Xatırladığımız kimi, Weld istifadə edəcəyik. Maraqlıdır ki, hər yerdə müxtəlif asılılıqlar verilir. Amma biz sənədlərə əməl edəcəyik. Buna görə də gəlin " 18.4.5. Sinif yolunun qurulması " nı oxuyaq və orada deyildiyi kimi edək:
<dependency>
	<groupId>org.jboss.weld.se</groupId>
	<artifactId>weld-se-core</artifactId>
	<version>3.0.5.Final</version>
</dependency>
Weld üçüncü sıra versiyalarının CDI 2.0-ı dəstəkləməsi vacibdir. Buna görə də, bu versiyanın API-sinə arxalana bilərik. İndi kod yazmağa hazırıq.
Asılılıq inyeksiyasına qısa ekskursiya və ya

CDI konteynerinin işə salınması

CDI bir mexanizmdir. Bu mexanizmə kimsə nəzarət etməlidir. Yuxarıda oxuduğumuz kimi, belə bir menecer konteynerdir. Buna görə də biz onu yaratmalıyıq, o, SE mühitində görünməyəcək. Əsas metodumuza aşağıdakıları əlavə edək:
public static void main(String[] args) {
	SeContainerInitializer initializer = SeContainerInitializer.newInstance();
	initializer.addPackages(App.class.getPackage());
	SeContainer container = initializer.initialize();
}
CDI konteynerini əl ilə yaratdıq, çünki... Biz SE mühitində işləyirik. Tipik döyüş layihələrində kod koda müxtəlif texnologiyalar təqdim edən serverdə işləyir. Müvafiq olaraq, əgər server CDI təmin edirsə, bu o deməkdir ki, serverdə artıq CDI konteyneri var və heç nə əlavə etməyimiz lazım olmayacaq. Lakin bu dərsliyin məqsədləri üçün biz SE mühitini götürəcəyik. Bundan əlavə, konteyner burada, aydın və başa düşüləndir. Niyə bir konteynerə ehtiyacımız var? İçərisində olan qabda lobya (CDI lobya) var.
Asılılıq inyeksiyasına qısa ekskursiya və ya

CDI paxlası

Beləliklə, lobya. CDI qutusu nədir? Bu, bəzi qaydalara əməl edən Java sinfidir. Bu qaydalar spesifikasiyanın " 2.2. Lobya hansı siniflərə aiddir? " bölməsində təsvir edilmişdir. Tətbiq sinfi ilə eyni paketə CDI lobya əlavə edək:
public class Logger {
    public void print(String message) {
        System.out.println(message);
    }
}
İndi bu paxlaya metodumuzdan zəng edə bilərik main:
Logger logger = container.select(Logger.class).get();
logger.print("Hello, World!");
Gördüyünüz kimi, biz lobyanı new açar sözündən istifadə edərək yaratmadıq. Biz CDI konteynerindən soruşduq: "CDI konteyneri. Mənə həqiqətən Logger sinfinin nümunəsinə ehtiyacım var, onu mənə verin." Bu üsul " Asılılıq axtarışı ", yəni asılılıqların axtarışı adlanır . İndi yeni bir sinif yaradaq:
public class DateSource {
    public String getDate() {
        return new Date().toString();
    }
}
Tarixin mətn təsvirini qaytaran primitiv sinif. İndi mesaja tarix çıxışını əlavə edək:
public class Logger {
    @Inject
    private DateSource dateSource;

    public void print(String message) {
        System.out.println(dateSource.getDate() + " : " + message);
    }
}
Maraqlı @Inject annotasiyası ortaya çıxdı. cdi qaynaq sənədlərinin " 4.1. Enjeksiyon nöqtələri " fəslində qeyd edildiyi kimi , bu qeyddən istifadə edərək biz Enjeksiyon nöqtəsini təyin edirik. Rus dilində bunu “tətbiq nöqtələri” kimi oxumaq olar. Onlar CDI konteyneri tərəfindən paxlaların yaradılması zamanı asılılıqlar daxil etmək üçün istifadə olunur. Gördüyünüz kimi, biz dateSource sahəsinə heç bir dəyər təyin etmirik. Bunun səbəbi, CDI konteynerinin CDI paxlalarının içərisində (yalnız özünün yaratdığı, yəni idarə etdiyi paxlaların) " Asılılıq Enjeksiyonu " ndan istifadə etməyə icazə verməsidir. Bu, Nəzarətin İnversiyasının başqa bir yoludur , asılılığın obyektləri açıq şəkildə yaratmaqdansa, başqası tərəfindən idarə olunduğu bir yanaşmadır. Asılılıq inyeksiyası metod, konstruktor və ya sahə vasitəsilə həyata keçirilə bilər. Ətraflı məlumat üçün CDI spesifikasiyasının " 5.5. Asılılıq inyeksiyası " bölməsinə baxın. Nəyin həyata keçirilməli olduğunu müəyyən etmək üçün prosedura tip təhlükəsiz rezolyusiya deyilir, bu barədə danışmalıyıq.
Asılılıq inyeksiyasına qısa ekskursiya və ya

Ad həlli və ya Typesafe həlli

Tipik olaraq, həyata keçiriləcək obyektin növü kimi interfeysdən istifadə olunur və CDI konteyneri hansı tətbiqin seçiləcəyini özü müəyyən edir. Bu, müzakirə edəcəyimiz bir çox səbəbə görə faydalıdır. Beləliklə, bizim logger interfeysimiz var:
public interface Logger {
    void print(String message);
}
Deyir ki, əgər bizim hansısa loggerimiz olsa, ona mesaj göndərə bilərik və o, öz vəzifəsini yerinə yetirəcək - log. Bu işdə necə və harada maraqlı olmayacaq. İndi logger üçün tətbiq yaradaq:
public class SystemOutLogger implements Logger {
    @Inject
    private DateSource dateSource;

    public void print(String message) {
        System.out.println(message);
    }
}
Gördüyünüz kimi, bu, System.out-a yazan bir loggerdir. Möhtəşəm. İndi bizim əsas metodumuz əvvəlki kimi işləyəcək. Logger logger = container.select(Logger.class).get(); Bu xətt hələ də logger tərəfindən qəbul ediləcək. Və gözəllik ondadır ki, biz yalnız interfeysi bilməliyik və CDI konteyneri artıq bizim üçün həyata keçirilməsi haqqında düşünür. Tutaq ki, jurnalı harasa uzaq yaddaşa göndərməli olan ikinci bir tətbiqimiz var:
public class NetworkLogger implements Logger {
    @Override
    public void print(String message) {
        System.out.println("Send log message to remote log system");
    }
}
İndi kodumuzu dəyişmədən işlətsək, xəta alacağıq, çünki CDI konteyneri interfeysin iki tətbiqini görür və onlar arasında seçim edə bilmir: org.jboss.weld.exceptions.AmbiguousResolutionException: WELD-001335: Ambiguous dependencies for type Logger Nə etməli? Bir neçə variasiya mövcuddur. Ən sadəi CDI paxlası üçün @Vetoed annotasiyasıdır ki, CDI konteyneri bu sinfi CDI paxlası kimi qəbul etməsin. Ancaq daha maraqlı bir yanaşma var. CDI paxlası Qaynaq CDI sənədlərinin @Alternative" 4.7. Alternativlər " fəslində təsvir edilən annotasiyadan istifadə edərək "alternativ" kimi qeyd oluna bilər . Bunun mənası nədi? Bu o deməkdir ki, biz açıq şəkildə istifadə etməyi deməsək, seçilməyəcək. Bu paxlanın alternativ variantıdır. NetworkLogger lobyasını @Alternative olaraq qeyd edək və kodun yenidən icra edildiyini və SystemOutLogger tərəfindən istifadə edildiyini görə bilərik. Alternativi aktivləşdirmək üçün beans.xml faylımız olmalıdır . Sual yarana bilər: " beans.xml, mən sizi hara qoyuram? " Beləliklə, faylı düzgün yerləşdirək:
Asılılıq inyeksiyasına qısa ekskursiya və ya
Bu faylı əldə etdikdən sonra kodumuz olan artefakt “ Açıq lobya arxivi ” adlandırılacaq . İndi 2 ayrı konfiqurasiyamız var: proqram təminatı və xml. Problem ondadır ki, onlar eyni məlumatları yükləyəcəklər. Məsələn, DataSource lobya tərifi 2 dəfə yüklənəcək və proqramımız icra edildikdə çökəcək, çünki CDI konteyneri onları 2 ayrı lobya kimi düşünəcək (baxmayaraq ki, onlar CDI konteynerinin iki dəfə öyrəndiyi eyni sinifdir). Bunun qarşısını almaq üçün 2 seçim var:
  • xətti çıxarın initializer.addPackages(App.class.getPackage())və xml faylına alternativin göstəricisini əlavə edin:
<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>
  • lobya kök elementinə " heç biribean-discovery-mode " dəyəri olan bir atribut əlavə edin və proqrama uyğun olaraq alternativ təyin edin:
initializer.addPackages(App.class.getPackage());
initializer.selectAlternatives(NetworkLogger.class);
Beləliklə, CDI alternativindən istifadə edərək konteyner hansı paxlanın seçiləcəyini müəyyən edə bilər. Maraqlıdır ki, əgər CDI konteyneri eyni interfeys üçün bir neçə alternativ bilirsə, biz bunu annotasiyadan istifadə edərək prioriteti göstərməklə deyə bilərik @Priority(CDI 1.1-dən bəri).
Asılılıq inyeksiyasına qısa ekskursiya və ya

Seçmələr

Ayrı-ayrılıqda, seçmələr kimi bir şeyi müzakirə etməyə dəyər. Kvalifikator paxlanın üstündəki annotasiya ilə göstərilir və lobya axtarışını dəqiqləşdirir. Və indi daha ətraflı. Maraqlıdır ki, hər hansı bir CDI paxlasının istənilən halda ən azı bir kvalifikatoru var - @Any. Əgər paxlanın yuxarısında HƏR nisbi təyin etməsək, lakin o zaman CDI konteynerinin özü @Anykvalifikatora başqa kvalifikator əlavə edir - @Default. Əgər biz nəyisə təyin etsək (məsələn, açıq şəkildə @Any göstərin), onda @Default kvalifikatoru avtomatik əlavə edilməyəcək. Ancaq seçmələrin gözəlliyi ondadır ki, siz öz seçmələrinizi edə bilərsiniz. Kvalifikator annotasiyalardan demək olar ki, fərqlənmir, çünki mahiyyət etibarı ilə bu, sadəcə olaraq xüsusi şəkildə yazılmış annotasiyadır. Məsələn, protokol növü üçün Enum daxil edə bilərsiniz:
public enum ProtocolType {
    HTTP, HTTPS
}
Sonra bu növü nəzərə alacaq bir seçici yarada bilərik:
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Protocol {
    ProtocolType value();
    @Nonbinding String comment() default "";
}
Qeyd etmək lazımdır ki, kimi qeyd olunan sahələr @Nonbindingseçicinin təyin edilməsinə təsir göstərmir. İndi kvalifikatoru təyin etməlisiniz. O, paxla növünün üstündə (CDI onu necə təyin edəcəyini bilsin) və Enjeksiyon Nöqtəsinin üstündə (@Inject annotasiyası ilə) göstərilir ki, siz bu yerdə inyeksiya üçün hansı paxlaya baxmaq lazım olduğunu başa düşəsiniz. Məsələn, müəyyən bir sinif əlavə edə bilərik. Sadəlik üçün, bu məqalə üçün onları NetworkLogger daxilində edəcəyik:
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");
	}
}
Və sonra biz Inject yerinə yetirdikdə, hansı sinfin istifadə olunacağına təsir edəcək kvalifikator təyin edəcəyik:
@Inject
@Protocol(ProtocolType.HTTPS)
private Sender sender;
Əla, elə deyilmi?) Gözəl görünür, amma niyə aydın deyil. İndi aşağıdakıları təsəvvür edin:
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);
Bu yolla biz əldə edilən dəyəri ləğv edə bilərik ki, dinamik olaraq hesablana bilsin. Məsələn, bəzi parametrlərdən götürülə bilər. Sonra proqramı/serveri yenidən tərtib etmədən və ya yenidən işə salmadan həyata keçirməyi hətta tez dəyişə bilərik. Daha maraqlı olur, elə deyilmi? )
Asılılıq inyeksiyasına qısa ekskursiya və ya

İstehsalçılar

CDI-nin digər faydalı xüsusiyyəti istehsalçılardır. Bunlar, bəzi lobya asılılıq inyeksiyasını tələb etdikdə çağırılan xüsusi üsullardır (onlar xüsusi annotasiya ilə qeyd olunur). Daha ətraflı məlumat sənədlərin " 2.2.3. İstehsalçı üsulları " bölməsində təsvir edilmişdir. Ən sadə misal:
@Produces
public Integer getRandomNumber() {
	return new Random().nextInt(100);
}
İndi Integer tipli sahələrə inyeksiya edərkən bu üsul çağırılacaq və ondan qiymət alınacaq. Burada dərhal başa düşməliyik ki, yeni açar sözünü görəndə dərhal başa düşməliyik ki, bu CDI lobya DEYİL. Yəni, Random sinifinin nümunəsi yalnız CDI konteynerinə nəzarət edən bir şeydən (bu halda istehsalçıdan) əldə edildiyi üçün CDI paxlasına çevrilməyəcək.
Asılılıq inyeksiyasına qısa ekskursiya və ya

Keçiricilər

Interceptorlar işə “müdaxilə edən” kəsicilərdir. CDI-də bu olduqca aydın şəkildə edilir. Gəlin görək tərcüməçilərdən (və ya ələ keçiricilərdən) istifadə edərək girişi necə edə bilərik. Birincisi, kəsici ilə əlaqəni təsvir etməliyik. Bir çox şey kimi, bu da annotasiyalardan istifadə etməklə həyata keçirilir:
@Inherited
@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface ConsoleLog {
}
@InterceptorBindingBurada əsas odur ki, bu , uzantılar ( ) tərəfindən miras alınacaq kəsici ( ) üçün bağlayıcıdır @InterceptorBinding. İndi kəsicinin özünü yazaq:
@Interceptor
@ConsoleLog
public class LogInterceptor {
    @AroundInvoke
    public Object log(InvocationContext ic) throws Exception {
        System.out.println("Invocation method: " + ic.getMethod().getName());
        return ic.proceed();
    }
}
Nümunədə kəsicilərin necə yazıldığı haqqında ətraflı məlumatı spesifikasiyadan oxuya bilərsiniz: " 1.3.6. Tutucu nümunə ". Yaxşı, etməli olduğumuz tək şey inerseptoru işə salmaqdır. Bunu etmək üçün icra olunan metodun üstündə bağlama annotasiyasını göstərin:
@ConsoleLog
public void print(String message) {
İndi başqa bir çox vacib detal. Interceptors default olaraq qeyri-aktivdir və alternativlər kimi aktivləşdirilməlidir. Məsələn, beans.xml faylında :
<interceptors>
	<class>ru.javarush.LogInterceptor</class>
</interceptors>
Gördüyünüz kimi, olduqca sadədir.
Asılılıq inyeksiyasına qısa ekskursiya və ya

Hadisə və Müşahidəçilər

CDI həmçinin hadisələrin və müşahidəçilərin modelini təqdim edir. Burada hər şey kəsicilərlə olduğu qədər aydın deyil. Beləliklə, bu vəziyyətdə Hadisə tamamilə hər hansı bir sinif ola bilər, təsvir üçün xüsusi bir şey tələb olunmur. Misal üçün:
public class LogEvent {
    Date date = new Date();
    public String getDate() {
        return date.toString();
    }
}
İndi kimsə hadisəni gözləməlidir:
public class LogEventListener {
    public void logEvent(@Observes LogEvent event){
        System.out.println("Message Date: " + event.getDate());
    }
}
Burada əsas şey @Observes annotasiyasını müəyyən etməkdir ki, bu da bunun sadəcə bir üsul olmadığını, LogEvent tipli hadisələrin müşahidəsi nəticəsində çağırılmalı olan bir metod olduğunu göstərir. Yaxşı, indi bizə baxacaq biri lazımdır:
public class LogObserver {
    @Inject
    private Event<LogEvent> event;
    public void observe(LogEvent logEvent) {
        event.fire(logEvent);
    }
}
Konteynerə LogEvent hadisə növü üçün Hadisənin baş verdiyini bildirəcək vahid metodumuz var. İndi yalnız müşahidəçidən istifadə etmək qalır. Məsələn, NetworkLogger-də müşahidəçimizin inyeksiyasını əlavə edə bilərik:
@Inject
private LogObserver observer;
Çap metodunda isə müşahidəçiyə yeni bir hadisəmiz olduğunu bildirə bilərik:
public void print(String message) {
	observer.observe(new LogEvent());
Hadisələrin bir və ya bir neçə mövzuda işlənə biləcəyini bilmək vacibdir. Asinxron emal üçün metoddan .fireAsync(.fire əvəzinə) və annotasiyadan @ObservesAsync(@Observes əvəzinə) istifadə edin. Məsələn, əgər bütün hadisələr müxtəlif cərəyanlarda icra olunursa, onda 1 ip İstisna atırsa, o zaman digərləri digər hadisələr üçün öz işlərini görə biləcəklər. Siz CDI-da hadisələr haqqında daha çox məlumatı, həmişə olduğu kimi, spesifikasiyanın " 10. Hadisələr " bölməsində oxuya bilərsiniz .
Asılılıq inyeksiyasına qısa ekskursiya və ya

Dekoratorlar

Yuxarıda gördüyümüz kimi, CDI qanadının altında müxtəlif dizayn nümunələri toplanır. Və burada başqa biri var - dekorativ. Bu çox maraqlı bir şeydir. Gəlin bu sinfə nəzər salaq:
@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);
    }
}
Onu dekorator elan etməklə, deyirik ki, hər hansı Logger tətbiqindən istifadə edildikdə, nümayəndə sahəsində saxlanılan real tətbiqi bilən bu “əlavə” istifadə olunacaq (annotasiya ilə qeyd olunduğu üçün ) @Delegate. Dekoratorlar yalnız bir CDI paxlası ilə əlaqələndirilə bilər, özü də nə kəsici, nə də dekorator. Nümunəni spesifikasiyada da görmək olar: " 1.3.7. Dekorator nümunəsi ". Dekorator, kəsici kimi, işə salınmalıdır. Məsələn, beans.xml -də :
<decorators>
	<class>ru.javarush.LoggerDecorator</class>
</decorators>
Ətraflı məlumat üçün qaynaq arayışına baxın: " Fəsil 10. Dekoratorlar ".

Həyat dövrü

Fasulyenin öz həyat dövrü var. Bu kimi bir şey görünür:
Asılılıq inyeksiyasına qısa ekskursiya və ya
Şəkildən göründüyü kimi, bizdə həyat dövrü geri çağırışları var. Bunlar, CDI konteynerinə paxlanın həyat dövrünün müəyyən mərhələsində müəyyən metodları çağırmağı söyləyəcək annotasiyalardır. Misal üçün:
@PostConstruct
public void init() {
	System.out.println("Inited");
}
Bu üsul bir CDI paxlası konteyner tərəfindən yaradıldıqda çağırılacaq. Eyni şey @PreDestroy ilə də baş verəcək, lobya artıq lazım olmadıqda məhv edilir. Əbəs yerə deyil ki, CDI akronimində C hərfi var - Kontekst. CDI-dəki lobya kontekstlidir, yəni onların həyat dövrü CDI konteynerində mövcud olduqları kontekstdən asılıdır. Bunu daha yaxşı başa düşmək üçün “ 7. Kontekstual nümunələrin həyat dövrü ” spesifikasiyası bölməsini oxumalısınız . Konteynerin özünün də bir həyat dövrü olduğunu bilməyə dəyər, bu barədə " Konteynerin həyat dövrü hadisələri "ndə oxuya bilərsiniz.
Asılılıq inyeksiyasına qısa ekskursiya və ya

Ümumi

Yuxarıda CDI adlı aysberqin ən ucuna baxdıq. CDI JEE spesifikasiyasının bir hissəsidir və JavaEE mühitində istifadə olunur. Spring istifadə edənlər CDI deyil, DI istifadə edirlər, yəni bunlar bir az fərqli spesifikasiyalardır. Ancaq yuxarıdakıları bilmək və başa düşmək, fikrinizi asanlıqla dəyişə bilərsiniz. Nəzərə alsaq ki, Spring CDI dünyasından annotasiyaları dəstəkləyir (eyni Inject). Əlavə materiallar: #Viaçeslav
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION