ฤดูใบไม้ผลิ: ทำไมเราถึงได้รับอินเทอร์เฟซโดยอัตโนมัติและไม่ใช่คลาสที่นำมาใช้


142

ตัวอย่าง

interface IA
{
  public void someFunction();
}

@Resource(name="b")
class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}

@Resource(name="c")
class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

class MyRunner
{

  @Autowire
  @Qualifier("b") 
  IA worker;

  worker.someFunction();
}

ใครสามารถอธิบายสิ่งนี้ให้ฉัน

  • ฤดูใบไม้ผลิรู้ได้อย่างไรว่าควรใช้ polymorphic ประเภทใด
  • ฉันต้องการ@Qualifierหรือ@Resourceไม่
  • เหตุใดเราจึงสอบถามอินเตอร์เฟซโดยอัตโนมัติ

10
คุณอัตโนมัติเชื่อมต่ออินเทอร์เฟซเพื่อให้คุณสามารถเชื่อมต่อในการใช้งานที่แตกต่างกัน - นั่นคือหนึ่งในจุดของการเข้ารหัสไปยังอินเตอร์เฟสไม่ใช่คลาส
เดฟนิวตัน

คุณต้องการใช้ในการดำเนินการที่แตกต่างกัน ฉันไม่เข้าใจคำถาม
Dave Newton

หากเรากำลังเดินสายในอินเทอร์เฟซจะเกิดอะไรขึ้นเมื่อมีวิธีการมองเห็นเริ่มต้นภายในคลาส Impl ที่ฉันต้องการเข้าถึง ฉันไม่สามารถเพิ่มวิธีการนั้นให้กับส่วนติดต่อได้เนื่องจากส่วนต่อประสานสาธารณะไม่สามารถมีตัวแก้ไขเริ่มต้นได้
jlewkovich

มีความเป็นไปได้ที่จะเทียบกับ Spring Autowiring class กับ interface?
OhadR

1
ฉันคิดว่าการสร้างส่วนต่อประสานสำหรับการนำไปใช้เพียงครั้งเดียวนั้นเป็นวิธีปฏิบัติที่โง่ที่ยอมรับในโลกจาวา ผลที่ได้คือรหัสขยะจำนวนมาก แต่ทุกคนมีความสุขที่ได้ปฏิบัติตามกฎของ SOLID และ OOP ใช้ guice และโยนสปริงในถังขยะของประวัติศาสตร์
avgolubev

คำตอบ:


224

ฤดูใบไม้ผลิรู้ได้อย่างไรว่าควรใช้ polymorphic ประเภทใด

ตราบใดที่มีการใช้งานอินเทอร์เฟซเพียงครั้งเดียวและการใช้งานนั้นมีการใส่คำอธิบายประกอบด้วยการ@Componentเปิดใช้งานการสแกนคอมโพเนนต์ของสปริงเฟรมเวิร์กสปริงสามารถหาคู่ (อินเตอร์เฟสการใช้งาน) หากไม่ได้เปิดใช้งานการสแกนส่วนประกอบคุณต้องกำหนด bean อย่างชัดเจนใน application-config.xml (หรือไฟล์กำหนดค่าสปริงที่เทียบเท่า)

ฉันต้องการ @Qualifier หรือ @Resource หรือไม่

เมื่อคุณมีการนำไปใช้มากกว่าหนึ่งรายการคุณจะต้องผ่านการรับรองแต่ละรายการและระหว่างการเดินสายอัตโนมัติคุณจะต้องใช้@Qualifierคำอธิบายประกอบเพื่อแทรกการใช้งานที่ถูกต้องพร้อมกับ@Autowiredคำอธิบายประกอบ หากคุณกำลังใช้ @Resource (ซีแมนทิกส์ J2EE) คุณควรระบุชื่อถั่วโดยใช้nameแอตทริบิวต์ของคำอธิบายประกอบนี้

เหตุใดเราจึงสอบถามอินเตอร์เฟซโดยอัตโนมัติ

ประการแรกมันเป็นแนวปฏิบัติที่ดีในการใช้โค้ดกับอินเตอร์เฟสโดยทั่วไป ประการที่สองในกรณีของฤดูใบไม้ผลิคุณสามารถฉีดการใช้งานใด ๆ ที่รันไทม์ กรณีการใช้งานทั่วไปคือการฉีดใช้งานจำลองในระหว่างขั้นตอนการทดสอบ

interface IA
{
  public void someFunction();
}


class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}


class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

class MyRunner
{
     @Autowire
     @Qualifier("b") 
     IA worker;

     ....
     worker.someFunction();
}

การกำหนดค่า bean ของคุณควรมีลักษณะเช่นนี้:

<bean id="b" class="B" />
<bean id="c" class="C" />
<bean id="runner" class="MyRunner" />

อีกทางเลือกหนึ่งถ้าคุณเปิดใช้งานการสแกนส่วนประกอบบนแพ็คเกจที่มีสิ่งเหล่านี้อยู่คุณควรทำให้แต่ละคลาสมีคุณสมบัติ@Componentดังนี้:

interface IA
{
  public void someFunction();
}

@Component(value="b")
class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}


@Component(value="c")
class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

@Component    
class MyRunner
{
     @Autowire
     @Qualifier("b") 
     IA worker;

     ....
     worker.someFunction();
}

จากนั้นworkerในการจะได้รับการฉีดด้วยตัวอย่างของการพิมพ์MyRunnerB


@stackoverflow การแก้ไขคำถามจะไม่สมเหตุสมผลรหัสใหม่เป็นของคำตอบ ไม่อย่างนั้นคำถามก็ไม่สมเหตุสมผลเพราะมันจะต้องตอบตัวเอง
Dave Newton

Vikdor - โปรดดูการแก้ไข นั่นเป็นวิธีที่ถูกต้องในการใส่คำอธิบายประกอบคลาสและวัตถุที่ฉีดหรือไม่
stackoverflow

1
@VictorDombrovsky @Autowired @Qualifier("a1") a;ถูกต้องหรือไม่
โชคดี

1
@ โชคดีฉันทำผิดพลาด ฉันหมายถึง@Autowired @Qualifier("a1") A a;
Victor Dombrovsky

1
คุณสามารถใช้ @Profile ในการนำไปใช้งานเพื่อควบคุมว่าควรจะใช้งานอินเทอร์เฟซใดสำหรับอินเทอร์เฟซนั้นผ่านทางอาร์กิวเมนต์ของโปรแกรมหรือคุณสมบัติของแอปพลิเคชัน
b15

1

นอกจากนี้อาจทำให้คำเตือนบางอย่างในบันทึกเช่นCglib2AopProxy ไม่สามารถใช้วิธีพร็อกซีได้ และเหตุผลอื่น ๆ อีกมากมายสำหรับสิ่งนี้อธิบายไว้ที่นี่เหตุใดจึงมีอินเทอร์เฟซ implementaion เดียวในบริการและเลเยอร์ dao เสมอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.