JavaRush /Блоги Java /Random-TG /Экскурсияи кӯтоҳ ба тазриқи вобастагӣ ё "CDI боз чӣ аст?"...
Viacheslav
Сатҳи

Экскурсияи кӯтоҳ ба тазриқи вобастагӣ ё "CDI боз чӣ аст?"

Дар гурӯҳ нашр шудааст
Асосе, ки дар он чаҳорчӯбаҳои маъмултарин ҳоло сохта шудаанд, тазриқи вобастагӣ мебошад. Ман тавсия медиҳам, ки мушаххасоти CDI дар ин бора чӣ мегӯяд, мо чӣ гуна қобorятҳои асосӣ дорем ва чӣ гуна онҳоро истифода бурда метавонем.
Экскурсияи мухтасар ба тазриқи вобастагӣ ё

Муқаддима

Ман мехоҳам ин баррасии кӯтоҳро ба чунин чизе, ба монанди 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 равзанаи "Иҷро"-ро кушоед ва cmd-ро иҷро кунед) ва аз Maven хоҳиш кунед, ки ҳама чизро барои мо иҷро кунад. Барои ин, Maven консепсияе дорад, ки архетип ном дорад: Maven Archetype .
Экскурсияи мухтасар ба тазриқи вобастагӣ ё
Пас аз он, дар саволҳои " Рақам интихоб кунед ё филтрро татбиқ кунед " ва " org.apache.maven.archetypes:maven-archetype-quickstart versionро интихоб кунед " танҳо Enterро пахш кунед. Баъдан, идентификаторҳои лоиҳаро ворид кунед, ки ба истилоҳ GAV (ниг. Дастури Конвенсияи номгузорӣ ).
Экскурсияи мухтасар ба тазриқи вобастагӣ ё
Пас аз эҷоди бомуваффақияти лоиҳа, мо навиштаҷоти "БОҲИДАНИ МУВАФФАКИЯТ"-ро хоҳем дид. Акнун мо метавонем лоиҳаи худро дар IDE дӯстдоштаамон кушоем.

Илова кардани CDI ба лоиҳа

Дар муқаддима, мо дидем, ки CDI дорои вебсайти ҷолиб - http://www.cdi-spec.org/ . Қисмати зеркашӣ мавҷуд аст, ки дар он ҷадвал мавҷуд аст, ки маълумоти заруриро дар бар мегирад:
Экскурсияи мухтасар ба тазриқи вобастагӣ ё
Дар ин ҷо мо мебинем, ки чӣ тавр Maven далели он, ки мо CDI API-ро дар лоиҳа истифода мебарем, тасвир мекунад. API интерфейси барномасозии барнома, яъне баъзе интерфейси барномасозӣ мебошад. Мо бо интерфейс кор мекунем, бе ташвиш дар бораи он, ки дар паси ин интерфейс чӣ кор мекунад ва чӣ тавр кор мекунад. API як бойгонии кӯзаест, ки мо онро дар лоиҳаи худ оғоз хоҳем кард, яъне лоиҳаи мо аз ин зарф вобаста аст. Аз ин рӯ, API CDI барои лоиҳаи мо вобастагӣ аст. Дар Maven, лоиҳа дар файлҳои POM.xml тасвир шудааст ( POM - Модели Объекти лоиҳа ). Вобастагӣ дар блоки вобастагӣ тасвир шудааст, ки мо бояд ба он як вуруди нав илова кунем:
<dependency>
	<groupId>javax.enterprise</groupId>
	<artifactId>cdi-api</artifactId>
	<version>2.0</version>
</dependency>
Тавре ки шумо шояд пай бурдед, мо миқёсро бо арзиши пешниҳодшуда муайян намекунем. Чаро чунин фарқият вуҷуд дорад? Ин миқёс маънои онро дорад, ки касе ба мо вобастагӣ медиҳад. Вақте ки барнома дар serverи Java EE кор мекунад, ин маънои онро дорад, ки server барномаро бо тамоми технологияҳои зарурии JEE таъмин мекунад. Ба хотири соддагии ин барраси, мо дар муҳити Java SE кор хоҳем кард, аз ин рӯ ҳеҷ кас ба мо ин вобастагӣ намедиҳад. Шумо метавонед маълумоти бештарро дар бораи доираи вобастагӣ дар ин ҷо хонед: " Миқёси вобастагӣ ". Хуб, мо ҳоло қобorяти кор бо интерфейсҳо дорем. Аммо ба мо низ ба амал баровардан лозим аст. Тавре ки мо дар хотир дорем, мо Weld-ро истифода мебарем. Ҷолиб он аст, ки вобастагии гуногун дар ҳама ҷо дода мешавад. Аммо мо ҳуҷҷатҳоро риоя хоҳем кард. Аз ин рӯ, биёед " 18.4.5. Танзими роҳи синф " -ро хонем ва мувофиқи он амал кунем:
<dependency>
	<groupId>org.jboss.weld.se</groupId>
	<artifactId>weld-se-core</artifactId>
	<version>3.0.5.Final</version>
</dependency>
Муҳим аст, ки versionҳои сатри сеюми Weld CDI 2.0 -ро дастгирӣ кунанд. Аз ин рӯ, мо метавонем ба API-и ин version такя кунем. Ҳоло мо барои навиштани 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-ро мегирем. Илова бар ин, контейнер дар ин ҷо аст, равшан ва фаҳмо. Чаро ба мо контейнер лозим аст? Контейнер дар дохor он лӯбиё (CDI лӯбиё) дорад.
Экскурсияи мухтасар ба тазриқи вобастагӣ ё

Лӯбиёи CDI

Пас, лӯбиё. Пойгоҳи CDI чист? Ин синфи Java аст, ки баъзе қоидаҳоро риоя мекунад. Ин қоидаҳо дар мушаххасот, дар боби " 2.2. Кадом навъҳои лӯбиёҳо ҳастанд? ". Биёед як лӯбиёи CDI-ро ба ҳамон бастаи синфи App илова кунем:
public class Logger {
    public void print(String message) {
        System.out.println(message);
    }
}
Акнун мо метавонем ин лӯбиёро аз mainусули худ даъват кунем:
Logger logger = container.select(Logger.class).get();
logger.print("Hello, World!");
Тавре ки шумо мебинед, мо лӯбиёро бо истифода аз калимаи нав эҷод накардаем. Мо аз контейнери 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 пайдо шуд. Тавре ки дар боби " 4.1. Нуқтаҳои сӯзандору "-и ҳуҷҷатҳои кафшери cdi гуфта шудааст, бо истифода аз ин эзоҳ мо Нуқтаи сӯзандоруро муайян мекунем. Дар забони русӣ инро метавон ҳамчун "нуқтаҳои амалӣ" хондан мумкин аст. Онҳо аз ҷониби контейнери CDI барои ворид кардани вобастагӣ ҳангоми эҷоди лӯбиё истифода мешаванд. Тавре ки шумо мебинед, мо ба майдони dateSource ягон арзиш таъин намекунем. Сабаби ин дар он аст, ки контейнери CDI дар дохor лӯбиёҳои CDI (танҳо он лӯбиёҳое, ки худаш эҷод кардааст, яъне он идора мекунад) имкон медиҳад, ки " Injection Dependency " -ро истифода барад. Ин як роҳи дигари Инversionи назорат аст , равишест, ки вобастагӣ аз ҷониби каси дигар идора карда мешавад, на мо ба таври возеҳ сохтани an objectҳо. Тазриқи вобастагӣ метавонад тавассути усул, созанда ё майдон анҷом дода шавад. Барои тафсилоти бештар, ба боби мушаххасоти CDI нигаред " 5.5. Тазриқи вобастагӣ ". Тартиби муайян кардани он чизе, ки бояд амалӣ карда шавад, ҳалли бехатарӣ номида мешавад, ки мо бояд дар бораи он сӯҳбат кунем.
Экскурсияи мухтасар ба тазриқи вобастагӣ ё

Ҳалли ном ё ҳалли 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(); Ин сатр то ҳол аз ҷониби қайдгир қабул карда мешавад. Ва зебоӣ дар он аст, ки мо танҳо бояд интерфейсро донем ва контейнери 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 Чӣ бояд кард? Якчанд вариантҳо мавҷуданд. Соддатаринаш шарҳи @Vetoed барои лӯбиёи CDI мебошад, то контейнери CDI ин синфро ҳамчун лӯбиёи CDI қабул накунад. Аммо як равиши ҷолибтаре вуҷуд дорад. Лӯбиёи CDI-ро метавон ҳамчун "алтернатива" бо истифода аз шарҳи @Alternativeдар боби " 4.7. Алтернативаҳо " -и ҳуҷҷатҳои Weld CDI тавсифшуда қайд кард. Ин чӣ маъно дорад? Ин маънои онро дорад, ки агар мо ба таври возеҳ нагӯем, ки онро истифода баред, он интихоб карда намешавад. Ин варианти алтернативии лӯбиё аст. Биёед лӯбиёи NetworkLoggerро ҳамчун @Alternative қайд кунем ва мо мебинем, ки code дубора иҷро мешавад ва аз ҷониби SystemOutLogger истифода мешавад. Барои фаъол кардани алтернатива, мо бояд файли beans.xml дошта бошем . Саволе ба миён меояд: " beans.xml, ман шуморо ба куҷо мегузорам? " Бинобар ин, биёед файлро дуруст ҷойгир кунем:
Экскурсияи мухтасар ба тазриқи вобастагӣ ё
Ҳамин ки мо ин файлро дорем, артефакт бо рамзи мо " Архиви равшани лӯбиё " номида мешавад. Ҳоло мо 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 якчанд алтернативаҳои як интерфейсро донад, мо метавонем онро бо нишон додани афзалият бо истифода аз шарҳ @Priority(аз CDI 1.1).
Экскурсияи мухтасар ба тазриқи вобастагӣ ё

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

Алоҳида, дар бораи чунин чизе ба монанди тахассусҳо муҳокима кардан меарзад. Квалификация бо тавзеҳи болои лӯбиё нишон дода мешавад ва ҷустуҷӯи лӯбиёро дақиқ мекунад. Ва ҳоло тафсилоти бештар. Ҷолиб он аст, ки ҳама гуна лӯбиёи CDI дар ҳама ҳолат ҳадди аққал як тахассус дорад - @Any. Агар мо ЯГОН тахассусиро дар болои лӯбиё муайян накунем, аммо худи контейнери CDI @Anyба тахассуси дигар хосият илова мекунад - @Default. Агар мо чизеро муайян кунем (масалан, ба таври возеҳ нишон диҳед @Any), пас квалификатори @Default ба таври худкор илова карда намешавад. Аммо зебоии тахассусҳо дар он аст, ки шумо метавонед тахассусҳои худро созед. Квалификатор аз эзоҳҳо тақрибан фарқ надорад, зеро аслан, ин танњо тафсирест, ки ба таври махсус навишта шудааст. Масалан, шумо метавонед барои намуди протокол Enum ворид кунед:
public enum ProtocolType {
    HTTP, HTTPS
}
Минбаъд мо метавонем тахассусеро созем, ки ин навъи онро ба инобат мегирад:
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Protocol {
    ProtocolType value();
    @Nonbinding String comment() default "";
}
Қобor зикр аст, ки майдонҳои ҳамчун аломатгузорӣ @Nonbindingба муайян кардани квалификация таъсир намерасонанд. Акнун шумо бояд квалификацияро муайян кунед. Он дар болои навъи лӯбиё (то он ки CDI медонад, ки онро чӣ гуна муайян кунад) ва дар болои Нуқтаи тазриқ (бо шарҳи @Inject) нишон дода шудааст, то шумо фаҳмед, ки кадом лӯбиёро барои тазриқ дар ин ҷо ҷустуҷӯ кунед). Масалан, мо метавонем баъзе синфҳоро бо тахассус илова кунем. Барои содда, барои ин мақола мо онҳоро дар дохor 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;
Аҷоиб, ҳамин тавр не?) Зебо ба назар мерасад, аммо чаро маълум нест. Энди қуйидагиларни тасаввур қorнг:
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 истеҳсолкунандагон аст. Инҳо усулҳои махсус мебошанд (онҳо бо тавзеҳи махсус қайд карда мешаванд), вақте ки баъзе лӯбиёҳо дархости тазриқи вобастагӣ доранд. Тафсилоти бештар дар ҳуҷҷатҳо дар фасли " 2.2.3. Усулҳои истеҳсолкунанда " тавсиф шудааст. Мисоли соддатарин:
@Produces
public Integer getRandomNumber() {
	return new Random().nextInt(100);
}
Ҳоло, ҳангоми воридшавӣ ба майдонҳои навъи Integer, ин усул даъват карда мешавад ва аз он арзиш ба даст меояд. Дар ин ҷо мо бояд фавран бифаҳмем, ки вақте ки мо калимаи навро мебинем, мо бояд фавран фаҳмем, ки ин лӯбиёи CDI НЕСТ. Яъне, як мисоли синфи Random танҳо аз он чизе, ки контейнери CDI-ро идора мекунад (дар ин ҳолат, истеҳсолкунанда) гирифта шудааст, лӯбиёи CDI нахоҳад шуд.
Экскурсияи мухтасар ба тазриқи вобастагӣ ё

Боздошткунандагон

Интерцепторҳо интерсепторҳое мебошанд, ки ба кор "халал" мекунанд. Дар CDI ин ба таври равшан анҷом дода мешавад. Биёед бубинем, ки чӣ тавр мо бо истифода аз тарҷумонҳо (ё интерсепторҳо) сабти ном карда метавонем. Аввалан, мо бояд пайвастшавиро ба интерсептор тавсиф кунем. Мисли бисёр чизҳо, ин бо истифода аз шарҳҳо анҷом дода мешавад:
@Inherited
@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface ConsoleLog {
}
Дар ин ҷо чизи асосӣ ин аст, ки ин ҳатмӣ барои interceptor аст ( @InterceptorBinding), ки аз тарафи extensions ( ) мерос мешавад @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 ". Хуб, мо танҳо бояд инерсепторро ба кор дарорем. Барои ин, шарҳи ҳатмиро дар болои усули иҷрошаванда муайян кунед:
@ConsoleLog
public void print(String message) {
Ва ҳоло як ҷузъиёти хеле муҳим. Interceptors ба таври нобаёнӣ ғайрифаъол карда мешаванд ва бояд ҳамон тавре ки алтернативаҳо фаъол карда шаванд. Масалан, дар файли 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());
    }
}
Дар ин ҷо чизи асосӣ ин муайян кардани шарҳи @Observes аст, ки нишон медиҳад, ки ин на танҳо усул, балки усулест, ки бояд дар натиҷаи мушоҳидаи рӯйдодҳои навъи 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) ва эзоҳро @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, ин "иловагӣ" истифода мешавад, ки татбиқи воқеиро медонад, ки дар майдони намояндагӣ нигоҳ дошта мешавад (зеро он бо эзоҳ қайд карда шудааст @Delegate). Ороишгаронро танҳо бо лӯбиёи CDI алоқаманд кардан мумкин аст, ки худаш на интерсептор ва на ороишгар аст. Намунаро дар мушаххасот низ дидан мумкин аст: " 1.3.7. Намунаи ороишгари ". Декоратор, ба монанди интерсептор, бояд ба кор андохта шавад. Масалан, дар beans.xml :
<decorators>
	<class>ru.javarush.LoggerDecorator</class>
</decorators>
Барои тафсилоти бештар ба истиноди кафшер нигаред: " Боби 10. Ороишгарон ".

Гардиши айём

Лӯбиёҳо давраи зиндагии худро доранд. Чунин ба назар мерасад:
Экскурсияи мухтасар ба тазриқи вобастагӣ ё
Тавре ки шумо аз расм мебинед, мо зангҳои ба истилоҳ давраи ҳаёт дорем. Ин эзоҳҳоест, ки ба контейнери CDI мегӯяд, ки усулҳои муайянро дар марҳилаи муайяни давраи зиндагии лӯбиё даъват кунад. Барои намуна:
@PostConstruct
public void init() {
	System.out.println("Inited");
}
Ин усул вақте даъват карда мешавад, ки лӯбиёи CDI аз ҷониби контейнер сохта мешавад. Ҳамин чиз бо @PreDestroy рӯй медиҳад, вақте ки лӯбиё ҳангоми лозим нест, нобуд карда мешавад. Бесабаб нест, ки ихтисораи CDI дорои ҳарфи C - Context мебошад. Лӯбиёҳо дар CDI контекстӣ мебошанд, яъне давраи зиндагии онҳо аз контекст, ки дар дохor контейнери CDI мавҷуд аст, вобаста аст. Барои беҳтар фаҳмидани ин, шумо бояд бахши мушаххасотро хонед " 7. Давраи ҳаёти мисолҳои контекстӣ ". Инчунин донистан лозим аст, ки худи контейнер як давраи ҳаёт дорад, ки шумо метавонед онро дар " Ҳодисаҳои давраи зиндагии контейнер " хонед.
Экскурсияи мухтасар ба тазриқи вобастагӣ ё

Ҳамагӣ

Дар боло мо ба нӯги айсберг бо номи CDI назар кардем. CDI қисми мушаххасоти JEE буда, дар муҳити JavaEE истифода мешавад. Онҳое, ки Spring-ро истифода мебаранд, CDI-ро истифода намебаранд, аммо DI, яъне инҳо мушаххасоти каме фарқ мекунанд. Аммо донистан ва фаҳмидани гуфтаҳои боло, шумо метавонед ба осонӣ ақидаи худро тағир диҳед. Бо назардошти он, ки Spring шарҳҳоро аз ҷаҳони CDI дастгирӣ мекунад (ҳамон Inject). Маводҳои иловагӣ: #Вячеслав
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION