คำอธิบายประกอบฟิลด์@Autowired
เป็นnull
เพราะฤดูใบไม้ผลิไม่ทราบเกี่ยวกับสำเนาMileageFeeCalculator
ที่คุณสร้างขึ้นด้วยnew
และไม่ทราบว่าจะได้รับมันอัตโนมัติ
คอนเทนเนอร์ Spring Inversion of Control (IoC)มีสามองค์ประกอบหลักตรรกะ: รีจิสตรี (เรียกว่าApplicationContext
) ของส่วนประกอบ (beans) ที่พร้อมใช้งานโดยแอปพลิเคชันระบบกำหนดค่าที่แทรกการพึ่งพาของวัตถุลงไป การพึ่งพากับ beans ในบริบทและตัวแก้ปัญหาการพึ่งพาที่สามารถดูการกำหนดค่าของถั่วที่แตกต่างกันจำนวนมากและกำหนดวิธีการสร้างอินสแตนซ์และกำหนดค่าในลำดับที่จำเป็น
คอนเทนเนอร์ IoC ไม่ใช่เวทมนต์และมันไม่มีทางรู้เกี่ยวกับวัตถุ Java เว้นแต่คุณจะแจ้งให้พวกเขาทราบ เมื่อคุณโทรnew
JVM จะเร่งการคัดลอกวัตถุใหม่และส่งตรงถึงคุณ - มันจะไม่ผ่านกระบวนการกำหนดค่า มีสามวิธีที่คุณสามารถกำหนดค่า bean ของคุณได้
ผมได้โพสต์ทั้งหมดของรหัสนี้ใช้ Spring Boot ที่จะเปิดตัวในโครงการ GitHub นี้ ; คุณสามารถดูโครงการที่ดำเนินการเต็มรูปแบบสำหรับแต่ละวิธีเพื่อดูทุกสิ่งที่คุณต้องการเพื่อให้มันทำงาน ติดแท็กด้วยNullPointerException
:nonworking
ฉีดถั่วของคุณ
ตัวเลือกที่ดีที่สุดคือการปล่อยให้สปริงทำการดึงถั่วออกทั้งหมด สิ่งนี้ต้องการรหัสน้อยที่สุดและสามารถบำรุงรักษาได้มากที่สุด ในการทำให้ autowiring ทำงานตามที่คุณต้องการให้ autowire MileageFeeCalculator
เช่นนี้:
@Controller
public class MileageFeeController {
@Autowired
private MileageFeeCalculator calc;
@RequestMapping("/mileage/{miles}")
@ResponseBody
public float mileageFee(@PathVariable int miles) {
return calc.mileageCharge(miles);
}
}
หากคุณจำเป็นต้องสร้างตัวอย่างใหม่ของวัตถุบริการของคุณสำหรับการร้องขอที่แตกต่างกันคุณยังสามารถใช้ในการฉีดโดยใช้ฤดูใบไม้ผลิขอบเขตถั่ว
แท็กที่ทำงานโดยการฉีด@MileageFeeCalculator
ออบเจ็กต์บริการ:working-inject-bean
ใช้ @Configurable
หากคุณต้องการให้วัตถุที่สร้างขึ้นnew
เพื่อเป็น autowired จริงๆคุณสามารถใช้@Configurable
คำอธิบายประกอบSpring พร้อมกับ AspectJ การคอมไพล์เวลารวบรวมเพื่อฉีดวัตถุของคุณ วิธีการนี้จะแทรกโค้ดลงในคอนสตรัคเตอร์ของวัตถุที่แจ้งเตือน Spring ว่ามีการสร้างขึ้นเพื่อให้ Spring สามารถกำหนดค่าอินสแตนซ์ใหม่ได้ สิ่งนี้ต้องการการกำหนดค่าเล็กน้อยในบิลด์ของคุณ (เช่นการคอมไพล์ด้วยajc
) และการเปิดใช้งานตัวจัดการการกำหนดค่ารันไทม์ของ Spring ( @EnableSpringConfigured
ด้วยไวยากรณ์ JavaConfig) วิธีการนี้ใช้โดยระบบ Roo Active Record เพื่ออนุญาตให้new
อินสแตนซ์ของเอนทิตีของคุณได้รับข้อมูลการคงอยู่ที่จำเป็น
@Service
@Configurable
public class MileageFeeCalculator {
@Autowired
private MileageRateService rateService;
public float mileageCharge(final int miles) {
return (miles * rateService.ratePerMile());
}
}
แท็กที่ทำงานโดยใช้@Configurable
กับวัตถุบริการ:working-configurable
การค้นหา bean ด้วยตนเอง: ไม่แนะนำ
วิธีนี้เหมาะสำหรับการเชื่อมต่อกับรหัสดั้งเดิมในสถานการณ์พิเศษเท่านั้น เกือบจะดีกว่าเสมอในการสร้างคลาสอะแด็ปเตอร์แบบซิงเกิลที่ Spring สามารถ autowire และรหัสดั้งเดิมสามารถเรียกใช้ได้
ในการทำเช่นนี้คุณต้องมีคลาสที่ Spring สามารถให้การอ้างอิงไปยังApplicationContext
วัตถุ:
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static ApplicationContext getContext() {
return context;
}
}
จากนั้นรหัสดั้งเดิมของคุณสามารถเรียกgetContext()
และดึงถั่วที่ต้องการได้:
@Controller
public class MileageFeeController {
@RequestMapping("/mileage/{miles}")
@ResponseBody
public float mileageFee(@PathVariable int miles) {
MileageFeeCalculator calc = ApplicationContextHolder.getContext().getBean(MileageFeeCalculator.class);
return calc.mileageCharge(miles);
}
}
แท็กที่ทำงานโดยการค้นหาวัตถุบริการด้วยตนเองในบริบทสปริง: working-manual-lookup
F
S
ในกรณีนี้ผ่านถั่วที่ต้องการF
เป็นพารามิเตอร์ถั่วอื่น ๆS
คอนสตรัคคอนสตรัคและอธิบายของกับS
@Autowire
อย่าลืมใส่คำอธิบายประกอบการเรียนของถั่วครั้งแรกด้วยF
@Component