JavaRush /Java блогы /Random-KK /Тәуелділік инъекциясына қысқаша экскурсия немесе «CDI тағ...
Viacheslav
Деңгей

Тәуелділік инъекциясына қысқаша экскурсия немесе «CDI тағы не?»

Топта жарияланған
Ең танымал фреймворктардың негізі қазір тәуелділік инъекциясы болып табылады. Мен CDI спецификациясында бұл туралы не айтылғанын, бізде қандай негізгі мүмкіндіктер бар және оларды қалай пайдалануға болатынын қарауды ұсынамын.
Тәуелділік инъекциясына қысқаша экскурсия немесе

Кіріспе

Мен осы қысқаша шолуды CDI сияқты нәрсеге арнағым келеді. Бұл не? CDI контексттер және тәуелділік енгізу дегенді білдіреді. Бұл тәуелділік инъекциясын және мәтінмәндерді сипаттайтын Java EE спецификациясы. Ақпарат алу үшін http://cdi-spec.org веб-сайтына жүгінуге болады . CDI спецификация (оның қалай жұмыс істеу керектігінің сипаттамасы, интерфейстер жиынтығы) болғандықтан, бізге оны пайдалану үшін іске асыру қажет болады. Осындай іске асырудың бірі Weld - http://weld.cdi-spec.org/ Тәуелділіктерді басқару және жобаны жасау үшін біз Maven - https://maven.apache.org пайдаланамыз . Сонымен, бізде Maven орнатылды, енді бізде рефератты түсінбеу үшін оны іс жүзінде түсінетін болады. Ол үшін біз Maven көмегімен жоба жасаймыз. Пәрмен жолын ашайық (Windows жүйесінде «Іске қосу» терезесін ашу және cmd орындау үшін Win+R пернелер тіркесімін пайдалануға болады) және Maven-ден біз үшін бәрін жасауын сұраңыз. Бұл үшін Maven-де архетип деп аталатын тұжырымдама бар: Maven Archetype .
Тәуелділік инъекциясына қысқаша экскурсия немесе
Осыдан кейін « Сандарды таңдаңыз немесе сүзгіні қолданыңыз » және « org.apache.maven.archetypes:maven-archetype-quickstart нұсқасын таңдаңыз » сұрақтарында жай ғана Enter пернесін басыңыз. Әрі қарай, GAV деп аталатын жоба идентификаторларын енгізіңіз ( Атау конвенциясының нұсқаулығын қараңыз ).
Тәуелділік инъекциясына қысқаша экскурсия немесе
Жоба сәтті жасалғаннан кейін біз «ТАБЫСТЫ ҚҰРУ» жазуын көреміз. Енді біз жобамызды сүйікті IDE-де аша аламыз.

Жобаға CDI қосу

Кіріспеде біз CDI-де қызықты веб-сайт бар екенін көрдік - http://www.cdi-spec.org/ . Жүктеп алу бөлімі бар, онда бізге қажетті деректерді қамтитын кесте бар:
Тәуелділік инъекциясына қысқаша экскурсия немесе
Мұнда біз жобада CDI API қолданатынымызды Maven қалай сипаттайтынын көре аламыз. API - қолданбалы бағдарламалау интерфейсі, яғни кейбір бағдарламалау интерфейсі. Біз интерфейстің артында не және қалай жұмыс істейтіні туралы алаңдамай интерфейспен жұмыс істейміз. API - бұл біз өз жобамызда қолдана бастайтын jar мұрағаты, яғни біздің жоба осы банкаға тәуелді бола бастайды. Сондықтан біздің жобаға арналған CDI API тәуелділік болып табылады. Maven жүйесінде жоба POM.xml файлдарында сипатталған ( POM - Жоба нысанының үлгісі ). Тәуелділіктер тәуелділіктер блогында сипатталған, оған жаңа жазба қосу керек:
<dependency>
	<groupId>javax.enterprise</groupId>
	<artifactId>cdi-api</artifactId>
	<version>2.0</version>
</dependency>
Сіз байқаған боларсыз, біз берілген мәнмен ауқымды көрсетпейміз. Неліктен мұндай айырмашылық бар? Бұл аумақ біреудің бізге тәуелділікті қамтамасыз ететінін білдіреді. Бағдарлама Java EE serverінде жұмыс істегенде, бұл server қолданбаны барлық қажетті JEE технологияларымен қамтамасыз ететінін білдіреді. Бұл шолудың қарапайымдылығы үшін біз Java SE ортасында жұмыс істейміз, сондықтан ешкім бізге бұл тәуелділікті бермейді. Тәуелділік ауқымы туралы қосымша ақпаратты мына жерден оқи аласыз: " Тәуелділік ауқымы ". Жарайды, бізде енді интерфейстермен жұмыс істеу мүмкіндігі бар. Бірақ бізге іске асыру да қажет. Еске салсақ, біз Weld қолданамыз. Бір қызығы, әр жерде әртүрлі тәуелділіктер беріледі. Бірақ біз құжаттаманы орындаймыз. Сондықтан, " 18.4.5. Сынып жолын орнату " бөлімін оқып , онда айтылғандай орындаңыз:
<dependency>
	<groupId>org.jboss.weld.se</groupId>
	<artifactId>weld-se-core</artifactId>
	<version>3.0.5.Final</version>
</dependency>
Weld үшінші жол нұсқалары CDI 2.0 қолдауы маңызды. Сондықтан біз осы нұсқаның 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 codeқа әртүрлі технологияларды беретін serverде жұмыс істейді. Тиісінше, егер 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 дәнекерлеу құжаттамасының " 4.1. Инъекция нүктелері " тарауында айтылғандай , осы annotationны пайдалана отырып, біз Инъекция нүктесін анықтаймыз. Орыс тілінде мұны «іске асыру нүктелері» деп оқуға болады. Оларды CDI контейнері бұршақтарды жасау кезінде тәуелділіктерді енгізу үшін пайдаланылады. Көріп отырғаныңыздай, біз dateSource өрісіне ешқандай мән бермейміз. Мұның себебі, CDI контейнерінің CDI бұршақтарының ішінде (тек өзі жасаған, яғни ол басқаратын бұршақтар) « Тәуелділік инъекциясын » пайдалануға мүмкіндік беретіндігі. Бұл Басқаруды инversionлаудың тағы бір жолы , тәуелділікті біз нысандарды нақты жасау емес, басқа біреу басқаратын тәсіл. Тәуелділік инъекциясын әдіс, конструктор немесе өріс арқылы жасауға болады. Қосымша мәліметтер алу үшін CDI спецификациясының " 5.5. Тәуелділік инъекциясы " тарауын қараңыз. Нені іске асыру керектігін анықтау proceduresасы қауіпсіз ажыратымдылық деп аталады, бұл туралы айту керек.
Тәуелділік инъекциясына қысқаша экскурсия немесе

Атау ажыратымдылығы немесе Typesafe ажыратымдылығы

Әдетте интерфейс іске асырылатын нысанның түрі ретінде пайдаланылады және 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(); Бұл жолды тіркеуші әлі де қабылдайды. Ал сұлулық мынада, біз тек интерфейсті білуіміз керек, ал CDI контейнері біз үшін іске асыру туралы ойлайды. Бізде журналды қашықтағы жадқа жіберуі керек екінші іске қосылды делік:
public class NetworkLogger implements Logger {
    @Override
    public void print(String message) {
        System.out.println("Send log message to remote log system");
    }
}
Енді codeымызды өзгертусіз іске қоссақ, қате пайда болады, себебі CDI контейнері интерфейстің екі іске асырылуын көреді және олардың арасында таңдай алмайды: org.jboss.weld.exceptions.AmbiguousResolutionException: WELD-001335: Ambiguous dependencies for type Logger Не істеу керек? Бірнеше нұсқалары бар. Ең қарапайымы - CDI бұршағына арналған @Vetoed annotationсы , сондықтан CDI контейнері бұл классты CDI бұршағы ретінде қабылдамайды. Бірақ әлдеқайда қызықты тәсіл бар. CDI бұршағын Weld CDI құжаттамасының " 4.7. Баламалар@Alternative " тарауында сипатталған annotationны пайдаланып "балама" ретінде белгілеуге болады . Бұл нені білдіреді? Бұл оны пайдалануды нақты айтпасақ, ол таңдалмайды дегенді білдіреді. Бұл бұршақтың балама нұсқасы. 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>
  • бұршақтың түбір элементіне " nonebean-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 біліктілігі автоматты түрде қосылмайды. Бірақ іріктеулердің әдемілігі - сіз өзіңіздің іріктеушілеріңізді жасай аласыз. Квалификацияның annotationлардан айырмашылығы жоқ дерлік, өйткені мәні бойынша, бұл ерекше түрде жазылған 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 оны қалай анықтау керектігін білуі үшін) және Инъекция нүктесінің үстінде (@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мен белгіленген). Толығырақ мәліметтер құжаттаманың " 2.2.3. Өндіруші әдістері " бөлімінде сипатталған. Ең қарапайым мысал:
@Produces
public Integer getRandomNumber() {
	return new Random().nextInt(100);
}
Енді Integer типті өрістерге енгізу кезінде бұл әдіс шақырылады және одан мән алынады. Мұнда біз new кілт сөзін көргенде, бұл CDI бұршағы ЕМЕС екенін бірден түсінуіміз керек. Яғни, Random класының данасы тек CDI контейнерін (бұл жағдайда өндіруші) басқаратын нәрседен алынғандықтан ғана CDI бұршағына айналмайды.
Тәуелділік инъекциясына қысқаша экскурсия немесе

Ұстағыштар

Кедергілер - жұмысқа «кедергі жасайтын» тосқауылдар. 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. Ұстағыш мысалы ". Бізге инерцепторды қосу ғана қалды. Бұл әрекетті орындау үшін орындалатын әдіс үстінде байланыстыру annotationсын көрсетіңіз:
@ConsoleLog
public void print(String message) {
Ал енді тағы бір өте маңызды деталь. Ұстағыштар әдепкі бойынша өшірілген және баламалар сияқты қосулы болуы керек. Мысалы, beans.xml файлында :
<interceptors>
	<class>ru.javarush.LogInterceptor</class>
</interceptors>
Көріп отырғаныңыздай, бұл өте қарапайым.
Тәуелділік инъекциясына қысқаша экскурсия немесе

Оқиға және бақылаушылар

CDI сонымен қатар оқиғалар мен бақылаушылардың үлгісін береді. Мұнда бәрі тосқауылдардағыдай анық емес. Сонымен, бұл жағдайда оқиға мүлдем кез келген класс болуы мүмкін; сипаттама үшін ерекше ештеңе қажет емес. Мысалы:
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());
    }
}
Мұнда ең бастысы - бұл жай ғана әдіс емес, LogEvent түріндегі оқиғаларды бақылау нәтижесінде шақырылатын әдіс екенін көрсететін @Observes annotationсын көрсету. Енді бізге қарайтын адам керек:
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 ағын Ерекше жағдайды шығарса, қалғандары басқа оқиғалар үшін өз жұмысын жасай алады. 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 тарау. Декораторлар ".

Өміршеңдік кезең

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

Барлығы

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