Açıklanan alan @Autowired
, null
Spring'in MileageFeeCalculator
oluşturduğunuz kopyayı new
bilmemesi ve otomatik bağlamayı bilmemesidir.
Spring Inversion of Control (IoC) konteynerinin üç ana mantıksal bileşeni vardır: ApplicationContext
uygulama tarafından kullanılabilen bileşenlerin (fasulye) bir kayıt defteri (denilen ), nesnelerin bağımlılıklarını eşleştirerek bunlara enjekte eden bir yapılandırma sistemi bağlamda fasulye ile bağımlılıklar ve birçok farklı fasulyenin yapılandırmasına bakıp bunları nasıl gerekli sırayla yapılandıracağınızı ve yapılandırabileceğinizi belirleyebilen bir bağımlılık çözücü.
IoC kapsayıcısı sihir değildir ve bunları bir şekilde bilgilendirmediğiniz sürece Java nesnelerini bilmenin bir yolu yoktur. Aradığınızda new
, JVM yeni nesnenin bir kopyasını başlatır ve doğrudan size teslim eder - asla yapılandırma işleminden geçmez. Fasulyelerinizi yapılandırmanın üç yolu vardır.
Gitmek için Spring Boot'u kullanarak bu kodun tümünü bu GitHub projesinde yayınladım ; çalışmasını sağlamak için ihtiyacınız olan her şeyi görmek için her yaklaşım için tam çalışan bir projeye bakabilirsiniz. Şununla etiketle NullPointerException
:nonworking
Fasulyenizi enjekte edin
En çok tercih edilen seçenek, Spring'in tüm fasülyelerinizi otomatik olarak bağlamasıdır; bu en az miktarda kod gerektirir ve en sürdürülebilir koddur. Otomatik kablolamanın istediğiniz gibi çalışmasını sağlamak için aşağıdakileri de otomatik olarak bağlayın MileageFeeCalculator
:
@Controller
public class MileageFeeController {
@Autowired
private MileageFeeCalculator calc;
@RequestMapping("/mileage/{miles}")
@ResponseBody
public float mileageFee(@PathVariable int miles) {
return calc.mileageCharge(miles);
}
}
Farklı istekler için hizmet nesnenizin yeni bir örneğini oluşturmanız gerekirse, yine de Bahar çekirdeği kapsamlarını kullanarak enjeksiyon kullanabilirsiniz .
@MileageFeeCalculator
Hizmet nesnesini enjekte ederek çalışan etiket :working-inject-bean
@ Yapılandırılabilir Kullan
Otomatik olarak bağlanmak new
için oluşturulan nesnelere gerçekten ihtiyacınız varsa , Nesnelerinizi enjekte etmek için AspectJ derleme zamanı dokuma ile birlikte Bahar @Configurable
ek açıklamasını kullanabilirsiniz . Bu yaklaşım, Spring'in yeni örneği yapılandırabilmesi için, Spring'i oluşturulduğunu bildiren nesnenizin yapıcısına kod ekler. Bu, derlemenizde biraz yapılandırma (derleme gibi ajc
) ve Spring'in çalışma zamanı yapılandırma işleyicilerini ( @EnableSpringConfigured
JavaConfig sözdizimi ile) açmayı gerektirir. Bu yaklaşım, Roo Aktif Kayıt sistemi tarafından new
varlıklarınızın örneklerinin gerekli kalıcılık bilgilerini enjekte etmesini sağlamak için kullanılır.
@Service
@Configurable
public class MileageFeeCalculator {
@Autowired
private MileageRateService rateService;
public float mileageCharge(final int miles) {
return (miles * rateService.ratePerMile());
}
}
@Configurable
Hizmet nesnesini kullanarak çalışan etiket :working-configurable
Manuel fasulye araması: önerilmez
Bu yaklaşım, yalnızca özel durumlarda eski kodlarla arayüz oluşturmak için uygundur. Spring'in otomatik olarak bağlayabileceği ve eski kodun çağırabileceği tek bir adaptör sınıfı oluşturmak neredeyse her zaman tercih edilir, ancak Spring uygulama içeriğinden doğrudan bir fasulye istemek mümkündür.
Bunu yapmak için, Spring'in ApplicationContext
nesneye referans verebileceği bir sınıfa ihtiyacınız vardır :
@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;
}
}
Daha sonra eski kodunuz getContext()
ihtiyaç duyduğu çekirdekleri arayabilir ve alabilir:
@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);
}
}
Hizmet içeriğini Spring bağlamında el ile arayarak çalışan etiket: working-manual-lookup
F
başka bir fasulyenin yapıcısının içine fasulye çağrılması olabilirS
. Bu durumda gerekli olan fasulye geçmesiF
için diğer fasulye için parametre olarakS
yapıcı ve yapıcısı açıklamaS
ile@Autowire
. İlk fasulye sınıf açıklama unutmayınF
ile@Component
.