JavaRush /Java Blog /Random-TL /tagsibol. Aralin 2. IoC/DI sa pagsasanay
Umaralikhon
Antas
Красноярск

tagsibol. Aralin 2. IoC/DI sa pagsasanay

Nai-publish sa grupo
At kaya... Sa nakaraang aralin, maikling sinuri namin ang teoretikal na bahagi ng IoC at DI. Nag-set up din kami ng pom.xml configuration file para sa aming proyekto. Ngayon nagsisimula kaming lumikha ng pangunahing bahagi ng programa. Una, ipapakita ko sa iyo kung paano lumikha ng isang programa nang walang IoC / DI. At pagkatapos ay direktang gagawa kami ng isang programa na independiyenteng nagpapakilala ng mga dependency. Iyon ay, ang kontrol ng code ay ipinapasa sa mga kamay ng balangkas (tunog katakut-takot). Habang pinamamahalaan namin ang programa, isipin na mayroong isang tiyak na kumpanya. At ang kumpanya (sa ngayon) ay may dalawang departamento: Java Development at Hiring Department. Hayaan ang klase na naglalarawan sa "Java Development Department" na magkaroon ng dalawang paraan: String getName() - pagbabalik ng pangalan ng empleyado, String getJob() - pagbabalik ng posisyon ng empleyado. (Listahan 1)
package org.example;

public class JavaDevelopment {

    public String getName(){
        return "Alexa";
    }

    public String getJob(){
        return "Middle Java developer";
    }
}
Hayaang ang klase na naglalarawan sa hiring department ay magkaroon ng input constructor na tumatanggap ng isang empleyado, at isang void displayInfo() na paraan na nagpapakita ng impormasyon tungkol sa mga empleyado. (Listahan 2)
package org.example;

public class HiringDepartment {
    private JavaDevelopment javaDevelopment;

    public HiringDepartment(JavaDevelopment javaDevelopment) {
        this.javaDevelopment = javaDevelopment;
    }

    public void displayInfo() {
        System.out.println("Name: " + javaDevelopment.getName());
        System.out.println("Job: " + javaDevelopment.getJob());
    }
}
Mayroon ding Main - isang klase na namamahala sa lahat ng departamento. (Listahan 3)
package org.example;

public class Main {
    public static void main(String ... args){
        JavaDevelopment javaDevelopment = new JavaDevelopment();
        HiringDepartment hiringDepartment = new HiringDepartment(javaDevelopment);

        hiringDepartment.displayInfo();
    }
}
Katatagan sa ngayon. Kapag pinapatakbo namin ang Main class nakukuha namin ang sumusunod na resulta:
Name: Alexa
Job: Middle Java developer
Ngayon isipin natin na ang kumpanya ay gumagana nang mahusay. Samakatuwid, nagpasya silang palawakin ang saklaw ng kanilang mga aktibidad at nagbukas ng departamento ng pagpapaunlad ng Python. At dito lumitaw ang tanong: Paano ilarawan ang departamentong ito sa antas ng programa? Sagot: kailangan mong "kopyahin at i-paste" kung saan mo kailangang ilarawan ang departamentong ito (ang magandang lumang paraan🙃). Una, likhain natin ang klase mismo, na maglalarawan sa departamento ng "Pythonists". (Listahan 4)
package org.example;

public class PythonDevelopment {
    public String getName(){
        return "Mike";
    }

    public String getJob(){
        return "Middle Python developer";
    }
}
At pagkatapos ay ililipat namin ito sa HiringDepartment. At walang sinasabi ang HiringDepartment tungkol sa departamentong ito. Samakatuwid, kakailanganin mong lumikha ng bagong object ng PythonDevelopment class at isang constructor na tumatanggap ng mga developer ng Python. Kakailanganin mo ring baguhin ang displayInfo() na paraan upang maipakita nito ang impormasyon nang tama. (Listahan 5)
package org.example;

public class HiringDepartment {
    private JavaDevelopment javaDevelopment;

    public HiringDepartment(JavaDevelopment javaDevelopment) {
        this.javaDevelopment = javaDevelopment;
    }


    //Тут создается отдел найма для Python - разработчиков
    private PythonDevelopment pythonDevelopment;

    public HiringDepartment(PythonDevelopment pythonDevelopment) {
        this.pythonDevelopment = pythonDevelopment;
    }

    //Тогда придется изменить метод displayInfo()
    public void displayInfo() {
        if(javaDevelopment != null) {
            System.out.println("Name: " + javaDevelopment.getName());
            System.out.println("Job: " + javaDevelopment.getJob());
        } else if (pythonDevelopment != null){
            System.out.println("Name: " + pythonDevelopment.getName());
            System.out.println("Job: " + pythonDevelopment.getJob());
        }
    }
}
Gaya ng nakikita natin, nadoble ang dami ng code, o higit pa. Sa malaking halaga ng code, bumababa ang pagiging madaling mabasa nito. At ang pinakamasama ay ang paggawa namin ng lahat ng mga bagay nang manu-mano at gumawa ng mga klase na lubos na nakadepende sa isa't isa. Okay, napagkasunduan namin ito. Inilarawan lang nila ang isang departamento. Wala tayong mawawala dito. Eh, paano kung magdagdag tayo ng ibang departamento? Paano kung dalawa? tatlo? Ngunit walang sinuman ang nagbabawal sa "pagmimina at pagpapastol." tagsibol.  Aralin 2. IoC / DI sa pagsasanay - 1 Oo, walang nagbabawal sa "Mine and Pasture", ngunit hindi ito propesyonal. Si Tyzh ay isang programmer. At dito maaari mong gamitin ang DI. Iyon ay, gagana kami hindi sa antas ng klase, ngunit sa antas ng interface. Ngayon ang mga estado ng aming mga bagay ay maiimbak sa mga interface. Sa ganitong paraan, magiging minimal ang mga dependency sa pagitan ng mga klase. Upang gawin ito, lumikha muna kami ng interface ng Pag-unlad, na may dalawang pamamaraan para sa paglalarawan ng isang empleyado. (Listahan 6)
package org.example;

public interface Development {
    String getName();
    String getJob();
}
Hayaan ang dalawang klase na JavaDevelopment at PythonDevelopment na magpatupad (magmana) mula sa interface na ito at i-override ang mga pamamaraan na String getName() at String getJob(). (Listahan 7, 8)
package org.example;

public class JavaDevelopment implements Development {
    @Override
    public String getName(){
        return "Alexa";
    }

    @Override
    public String getJob(){
        return "Middle Java developer";
    }
}
package org.example;

public class PythonDevelopment implements Development {
    @Override
    public String getName(){
        return "Mike";
    }

    @Override
    public String getJob(){
        return "Middle Python developer";
    }
}
Pagkatapos sa klase ng HiringDepartment maaari mo lamang tukuyin ang isang interface object ng uri ng Development at maaari mo ring ipasa ang naturang object sa constructor. (Listahan 9)
package org.example;

public class HiringDepartment {
    private Development development; //Определяем интерфейс

    //Конструктор принимает an object интерфейса
    public HiringDepartment(Development development){
        this.development = development;
    }

    public void displayInfo(){
        System.out.println("Name: " + development.getName());
        System.out.println("Job: " + development.getJob());
    }
}
Tulad ng nakikita natin, ang halaga ng code ay nabawasan. At higit sa lahat, nabawasan ang mga dependency. Paano aktwal na ipinapatupad ang mga halaga at dependency para sa mga bagay na ito? May tatlong paraan para gawin ang dependency injection:
  • Gamit ang constructor
  • Gamit ang mga setter
  • Autowiring (awtomatikong pagbubuklod)
Pagpapatupad gamit ang isang constructor Ngayon ay pag-usapan natin ang tungkol sa pagpapatupad gamit ang isang constructor. Tingnan ang Listahan 9. Inaasahan ng constructor ng klase ng HiringDepartment ang isang object ng uri ng Development bilang input. Susubukan naming mag-inject ng mga dependency sa pamamagitan ng constructor na ito. Kapansin-pansin din na ang dependency injection ay ginagawa gamit ang tinatawag na Spring containers. Mayroong tatlong paraan upang i-configure ang mga lalagyan ng Spring:
  • Paggamit ng mga XML file (Hindi napapanahong paraan)
  • Paggamit ng mga anotasyon + XML file (Modernong paraan)
  • Paggamit ng Java code (Modernong paraan)
Ginagamit namin ngayon ang pagsasaayos gamit ang mga XML file. Sa kabila ng katotohanan na ang pamamaraang ito ay itinuturing na lipas na, maraming mga proyekto ang nakasulat pa rin sa ganitong paraan. Samakatuwid kailangan mong malaman. Una, dapat kang lumikha ng isang xml file sa folder ng mapagkukunan. Maaari mo itong bigyan ng anumang pangalan, ngunit mas mabuti ang isang makahulugan. Tinawag ko itong "applicationContext.xml". tagsibol.  Aralin 2. IoC / DI sa pagsasanay - 2 Sa file na ito isusulat namin ang sumusunod na piraso ng code (Listing 10):
<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="javaDeveloper" class="org.example.JavaDevelopment"/>
    <bean id="pythonDeveloper" class="org.example.PythonDevelopment"/>

    <bean id="hiringDepartment" class="org.example.HiringDepartment">
        <constructor-arg ref="javaDeveloper"/>
    </bean>

</beans>
Ngayon, sa pagkakasunud-sunod. Ang unang walong linya ng code ay hindi kawili-wili sa amin, ang mga ito ay default. Maaari mong kopyahin lamang ang mga ito. Ang tag na <bean> </bean> ay tumutukoy sa isang Spring bean. Ang bean ay isang bagay na nilikha at pinamamahalaan ng isang lalagyan ng Spring. Sa simpleng salita, ang Spring container mismo ay gumagawa ng bagong class object para sa amin (halimbawa: JavaDevelopment javaDevelopment = new JavaDevelopment();). Sa loob ng tag na ito ay may mga katangian ng id at klase. Tinutukoy ng id ang pangalan ng bean. Gagamitin ang id na ito para ma-access ang object. Ito ay katumbas ng pangalan ng isang bagay sa isang klase ng Java. class - tumutukoy sa pangalan ng klase kung saan nakatali ang ating bean (object). Dapat mong tukuyin ang buong landas sa klase. Bigyang-pansin ang hiringDepartment bean. Sa loob ng bean na ito ay may isa pang <constructor-arg ref="javaDeveloper"/> tag. Dito nangyayari ang dependency injection (sa aming kaso, iniksyon gamit ang isang constructor). <constructor-arg> - nagsasabi sa Spring na ang Spring container ay dapat maghanap ng mga dependencies sa class constructor na tinukoy sa bean attribute. At kung aling object ang kailangang iugnay ay tinutukoy ng ref attribute , sa loob ng <constructor-arg> tag. ref - nagsasaad ng id ng bean na kokontakin. Kung sa ref sa halip na javaDeveloper ay tinukoy namin ang id pythonDeveloper, kung gayon ang koneksyon ay nangyayari sa PythonDevelopmen class. Ngayon kailangan nating ilarawan ang Pangunahing klase. Magiging ganito ang hitsura: (Listing11)
package org.example;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String ... args){
        //Определяем контекст файл в котором содержатся прописанные нами бины
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //Получем бины, которые были определены в файле applicationContext.xml
        HiringDepartment hiringDepartment = context.getBean("hiringDepartment", HiringDepartment.class);

        hiringDepartment.displayInfo();

        context.close(); //Контекст всегда должен закрываться
    }
}
Anong meron dito?
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Iniuugnay ng linyang ito ang Pangunahing klase sa .xml file na naglalarawan sa aming mga beans. Ang value na ipinasa sa constructor ay dapat tumugma sa pangalan ng .xml file. (Sa aming kaso applicationContext.xml).
HiringDepartment hiringDepartment = context.getBean("hiringDepartment", HiringDepartment.class);
Isinasaad na gusto naming makakuha ng bean (object) ng HiringDepartment class. Ang unang argumento ay tumuturo sa bean id na isinulat namin sa xml file. Ang pangalawang argumento ay tumuturo sa klase na gusto nating kontakin. Ang prosesong ito ay tinatawag na reflection .
hiringDepartment.displayInfo();
 context.close(); //Контекст всегда должен закрываться
Dito madali tayong nakakakuha ng paraan ng klase ng HiringDepartment. Tandaan na hindi namin ginamit ang bagong keyword upang makuha ang mga bagay, at hindi namin tinukoy ang mga umaasang bagay na may uri ng JavaDevelopment o PythonDevelopment kahit saan. Inilarawan lamang ang mga ito sa applicationContext.xml file. Bigyang-pansin din ang huling linya. Dapat mong palaging isara ang konteksto bago isara. Kung hindi, hindi mapapalaya ang mga mapagkukunan, at maaaring magkaroon ng memory leak o maling operasyon ng program. Kung mayroon kang mga katanungan o mungkahi, magsulat sa mga komento, tiyak na sasagutin ko. Salamat sa atensyon. Source code sa link Ang nilalaman ng My GitHub Cart Course ay ipagpapatuloy...
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION