Spring @ Autowired alanım neden boş?


609

Not: Bu, ortak bir sorunun kanonik bir cevabı olarak düşünülmüştür.

Bir alan @Service( MileageFeeCalculator) olan bir Spring sınıfı ( ) var , ama onu kullanmaya çalıştığınızda alan . Günlükler hem fasulye hem de fasülyenin yaratıldığını gösterir, ancak servis fasulyemdeki yöntemi çağırmaya çalıştığımda bir an alırım . Spring neden sahada otomatik kablolama yapmıyor?@AutowiredrateServicenullMileageFeeCalculatorMileageRateServiceNullPointerExceptionmileageCharge

Denetleyici sınıfı:

@Controller
public class MileageFeeController {    
    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        MileageFeeCalculator calc = new MileageFeeCalculator();
        return calc.mileageCharge(miles);
    }
}

Hizmet sınıfı:

@Service
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService; // <--- should be autowired, is null

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile()); // <--- throws NPE
    }
}

Otomatik bağlanması gereken servis çekirdeği, MileageFeeCalculatorancak:

@Service
public class MileageRateService {
    public float ratePerMile() {
        return 0.565f;
    }
}

Bunu denediğimde GET /mileage/3, bu istisnayı alıyorum:

java.lang.NullPointerException: null
    at com.chrylis.example.spring_autowired_npe.MileageFeeCalculator.mileageCharge(MileageFeeCalculator.java:13)
    at com.chrylis.example.spring_autowired_npe.MileageFeeController.mileageFee(MileageFeeController.java:14)
    ...

3
Başka bir senaryo, Fbaşka bir fasulyenin yapıcısının içine fasulye çağrılması olabilir S. Bu durumda gerekli olan fasulye geçmesi Fiçin diğer fasulye için parametre olarak Syapıcı ve yapıcısı açıklama Sile @Autowire. İlk fasulye sınıf açıklama unutmayın File @Component.
aliopi

Gradle'ı kullanarak buna çok benzer birkaç örnek kodladım: github.com/swimorsink/spring-aspectj-examples . Umarım birisi faydalı bulur.
Ross117

Yanıtlar:


649

Açıklanan alan @Autowired, nullSpring'in MileageFeeCalculatoroluşturduğunuz kopyayı newbilmemesi ve otomatik bağlamayı bilmemesidir.

Spring Inversion of Control (IoC) konteynerinin üç ana mantıksal bileşeni vardır: ApplicationContextuygulama 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 .

@MileageFeeCalculatorHizmet nesnesini enjekte ederek çalışan etiket :working-inject-bean

@ Yapılandırılabilir Kullan

Otomatik olarak bağlanmak newiçin oluşturulan nesnelere gerçekten ihtiyacınız varsa , Nesnelerinizi enjekte etmek için AspectJ derleme zamanı dokuma ile birlikte Bahar @Configurableek 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 ( @EnableSpringConfiguredJavaConfig sözdizimi ile) açmayı gerektirir. Bu yaklaşım, Roo Aktif Kayıt sistemi tarafından newvarlı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());
    }
}

@ConfigurableHizmet 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 ApplicationContextnesneye 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


1
Bakılması gereken diğer bir şey, @Configurationbelirli bir fasulye sınıfının bir örneğini yapma yönteminin açıklandığı bir fasulye içindeki fasulye için nesneler yapmaktır @Bean.
Donal Fellows

@DonalFellows Neden bahsettiğinizden tam olarak emin değilim ("yapmak" belirsiz). @BeanSpring Proxy AOP kullanırken yöntemlere birden çok çağrı ile ilgili bir sorundan mı bahsediyorsunuz ?
chrylis -cautiouslyoptimistic-

1
Merhaba, ben benzer bir sorunla karşılaşıyorum, ancak ilk öneriyi kullandığımda, benim uygulama "mileageFee" yöntemi çağırırken "calc" boş olduğunu düşünüyor. Sanki hiç başlatmamış gibi @Autowired MileageFeeCalculator calc. Düşüncesi olan var mı?
Theo

Sanırım cevabınızın en üstüne, her şeyi yaptığınız ilk fasulyeyi almanın, üzerinden yapılması gerektiğini açıklayan bir giriş eklemelisiniz ApplicationContext. Bazı kullanıcılar (kopyalarını kapattığım) bunu anlamıyor.
Sotirios Delimanolis

@SotiriosDelimanolis Lütfen sorunu açıklayın; Tam olarak hangi noktaya geldiğinizden emin değilim.
chrylis -cautiouslyoptimistic-

59

Bir web uygulaması kodlamıyorsanız, @Autowiring'in yapıldığı sınıfınızın bir bahar fasulyesi olduğundan emin olun. Tipik olarak, yay kabı, bir bahar çekirdeği olarak düşünebileceğimiz sınıfın farkında olmayacaktır. Bahar konteynerine bahar derslerimizden bahsetmeliyiz.

Bu, appln-contxt içinde yapılandırılarak sağlanabilir veya daha iyi bir yol , sınıfı @Component olarak açıklamaktır ve lütfen ek açıklamalı sınıfı yeni işleç kullanarak oluşturmayın. Aşağıdaki gibi Appln-context'den aldığınızdan emin olun.

@Component
public class MyDemo {


    @Autowired
    private MyService  myService; 

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
            System.out.println("test");
            ApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");
            System.out.println("ctx>>"+ctx);

            Customer c1=null;
            MyDemo myDemo=ctx.getBean(MyDemo.class);
            System.out.println(myDemo);
            myDemo.callService(ctx);


    }

    public void callService(ApplicationContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("---callService---");
        System.out.println(myService);
        myService.callMydao();

    }

}

merhaba, çözümünüzden geçtim, doğru. Ve burada bilmek istiyorum "Neden yeni operatör kullanarak açıklamalı sınıf örneği oluşturmuyoruz, bunun nedenini öğrenebilir miyim?
Ashish

3
Eğer nesneyi yeni kullanarak yaratırsanız, IOC kavramıyla çelişen çekirdeğin yaşam döngüsünü idare edeceksiniz. Konteynırdan daha iyi bir şekilde
yapmasını istedik

41

Aslında, yöntemleri çağırmak için JVM tarafından yönetilen Nesneler veya Yay tarafından yönetilen Nesne'yi kullanmalısınız. denetleyici sınıfınızdaki yukarıdaki kodunuzdan, otomatik kablolu bir nesneye sahip hizmet sınıfınızı çağırmak için yeni bir nesne oluşturuyorsunuz.

MileageFeeCalculator calc = new MileageFeeCalculator();

yani bu şekilde çalışmaz.

Çözüm, bu MileageFeeCalculator'ı Denetleyicinin kendisinde otomatik kablolu bir nesne olarak yapar.

Controller sınıfınızı aşağıdaki gibi değiştirin.

@Controller
public class MileageFeeController {

    @Autowired
    MileageFeeCalculator calc;  

    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        return calc.mileageCharge(miles);
    }
}

4
Cevap bu. Kendi başınıza yeni bir MilageFeeCalculator somutlaştırdığınız için, Spring somutlaştırmaya dahil değildir, bu nedenle Spring spring'in nesnenin var olduğu hakkında hiçbir bilgisi yoktur. Böylece, enjekte bağımlılıkları gibi, hiçbir şey yapamaz.
Robert Greathouse

26

Bir zamanlar pek alışkın olmadığımda aynı sorunla karşılaştım the life in the IoC world. @AutowiredBenim fasulye birinin tarla zamanında boş.

Kök neden yerine (kimin Bahar IoC kapsayıcı tarafından tutulan Otomatik oluşturulan fasulye kullanmak yerine, olduğu @Autowiredalan olan indeeddüzgün enjekte), öyleyim newingkendi o fasulye türünün örneği ve kullanma. Tabii ki bu @Autowiredalanın boş olması, çünkü Bahar'ın enjekte etme şansı yok.


22

Sorununuz yeni (Java tarzında nesne oluşturma)

MileageFeeCalculator calc = new MileageFeeCalculator();

Ek açıklama ile @Service, @Component, @Configurationfasulye oluşturulan
sunucu başlatıldığında Bahar uygulama bağlamında. Ancak yeni işleç kullanarak nesneler oluşturduğumuzda, nesne zaten oluşturulmuş olan uygulama bağlamında kaydedilmez. Örneğin Employee.java sınıfını kullandım.

Şuna bir bak:

public class ConfiguredTenantScopedBeanProcessor implements BeanFactoryPostProcessor {

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    String name = "tenant";
    System.out.println("Bean factory post processor is initialized"); 
    beanFactory.registerScope("employee", new Employee());

    Assert.state(beanFactory instanceof BeanDefinitionRegistry,
            "BeanFactory was not a BeanDefinitionRegistry, so CustomScope cannot be used.");
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

    for (String beanName : beanFactory.getBeanDefinitionNames()) {
        BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
        if (name.equals(definition.getScope())) {
            BeanDefinitionHolder proxyHolder = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(definition, beanName), registry, true);
            registry.registerBeanDefinition(beanName, proxyHolder.getBeanDefinition());
        }
    }
}

}

12

Spring'de yeniyim, ama bu çalışma çözümünü keşfettim. Lütfen bana bunun uygunsuz bir yol olup olmadığını söyleyin.

applicationContextBu fasulyeye bahar enjeksiyonu yapıyorum :

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class SpringUtils {

    public static ApplicationContext ctx;

    /**
     * Make Spring inject the application context
     * and save it on a static variable,
     * so that it can be accessed from any point in the application. 
     */
    @Autowired
    private void setApplicationContext(ApplicationContext applicationContext) {
        ctx = applicationContext;       
    }
}

İsterseniz bu kodu ana uygulama sınıfına da koyabilirsiniz.

Diğer sınıflar bu şekilde kullanılabilir:

MyBean myBean = (MyBean)SpringUtils.ctx.getBean(MyBean.class);

Bu şekilde herhangi bir fasulye, uygulamadaki herhangi bir nesne tarafından (ayrıca başlatılan new) ve statik bir şekilde elde edilebilir .


1
Bu model, Bahar çekirdeklerini eski koda erişilebilir hale getirmek için gereklidir, ancak yeni kodda kullanılmamalıdır.
chrylis -koutiouslyoptimistic-

2
Spring'de yeni değilsin. Sen bir profesyonelsin. :)
Ocak'ta sapy

beni kurtardın ...
Govind Singh

Benim durumumda bunu zorunlu kıldım çünkü az sayıda üçüncü taraf sınıfı vardı. Bahar (IOC) üzerinde kontrol sahibi değildi. Bu sınıflar asla bahar çizme uygulamamdan çağrılmadı. Bu yaklaşımı izledim ve benim için çalıştı.
Joginder Malik

12

Nadir görülen bir durum gibi görünüyor ama işte başıma gelenler:

Biz kullanılan @Injectyerine @Autowiredhangi Bahar tarafından desteklenen JavaEE standardıdır. Her yerde iyi çalıştı ve fasulye bir yer yerine doğru enjekte edildi. Fasulye enjeksiyonu aynı görünüyor

@Inject
Calculator myCalculator

Sonunda hatanın (aslında Eclipse otomatik tamamlama özelliği) com.opensymphony.xwork2.Injectyerine içe aktarıldığımız olduğunu fark ettik javax.inject.Inject!

Yani emin açıklamalarınız (yani, marka özetlemek @Autowired, @Inject, @Service, ...) Doğru paketleri var!


5

Bence baharı ek açıklama ile sınıfları taramaya talimat vermeyi kaçırdınız.

@ComponentScan("packageToScan")Yayı taramaya talimat vermek için yay uygulamanızın yapılandırma sınıfında kullanabilirsiniz .

@Service, @Component vb ek açıklamalar meta açıklama ekler.

Spring, yalnızca sınıf olarak fasulye olarak oluşturulan veya ek açıklama ile işaretlenmiş olan örnekleri enjekte eder.

Ek açıklama ile işaretlenmiş sınıfların, enjekte edilmeden önce bahar ile tanımlanması gerekir @ComponentScan, ek açıklama ile işaretlenmiş sınıflar için bahar görünümüne talimat verin. Spring bulduğunda @Autowiredilgili fasulyeyi arar ve gerekli örneği enjekte eder.

Yalnızca ek açıklama eklemek, bağımlılık enjeksiyonunu düzeltmez veya kolaylaştırmaz, Spring'in nereye bakacağını bilmesi gerekir.


bu işe koştu i eklemeyi unuttuğu zaman <context:component-scan base-package="com.mypackage"/>benim için beans.xmldosyanın
Ralph Callaway

5

Bu bir test sınıfında oluyorsa, sınıfa açıklama eklemeyi unutmadığınızdan emin olun.

Örneğin, Spring Boot'da :

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {
    ....

Biraz zaman geçti ...

Spring Boot gelişmeye devam ediyor . @RunWith Doğru JUnit sürümünü kullanıyorsanız artık kullanmanız gerekmez .

İçin @SpringBootTestişe tek başına, sen kullanımına ihtiyaç @Testden JUnit5 yerine JUnit4 .

//import org.junit.Test; // JUnit4
import org.junit.jupiter.api.Test; // JUnit5

@SpringBootTest
public class MyTests {
    ....

Eğer bu yapılandırma yanlış alırsanız sizin testler derlemek, ancak @Autowiredve @Valuealanlar (örneğin) olacaktır null. Spring Boot sihirle çalıştığı için, bu hatayı doğrudan hata ayıklamak için birkaç yolunuz olabilir.



Not: alanlarla @Valuekullanıldığında boş olacaktır static.
nobar

Spring, başarısız olmanın sayısız yolunu sunar (derleyiciden yardım almadan). İşler ters gittiğinde, en iyi seçeneğiniz, yalnızca birlikte çalışacağını bildiğiniz ek açıklamaların birleşimini kullanarak kare olana dönmektir.
nobar

4

Başka bir çözüm şöyle SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this)
diyordu : MileageFeeCalculator yapıcısına şöyle:

@Service
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService; // <--- will be autowired when constructor is called

    public MileageFeeCalculator() {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this)
    }

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile()); 
    }
}

Bu, güvenli olmayan yayın kullanır.
chrylis -cautiouslyoptimistic-

3

GÜNCELLEME: Gerçekten akıllı insanlar , aşağıda açıklanan garipliği açıklayan bu cevaba hızlıca yöneldi

ORİJİNAL CEVAP:

Kimseye yardım edip etmediğini bilmiyorum, ama görünüşe göre doğru şeyler yaparken bile aynı sorunla karşılaştım. Benim ana yöntemde, böyle bir kod var:

ApplicationContext context =
    new ClassPathXmlApplicationContext(new String[] {
        "common.xml",
        "token.xml",
        "pep-config.xml" });
    TokenInitializer ti = context.getBean(TokenInitializer.class);

ve bir token.xmldosyada bir satırım vardı

<context:component-scan base-package="package.path"/>

Paket yolunun artık mevcut olmadığını fark ettim, bu yüzden çizgiyi iyice düşürdüm.

Ve bundan sonra NPE içeri girmeye başladı. Bir tane pep-config.xmlsadece 2 fasulyem vardı:

<bean id="someAbac" class="com.pep.SomeAbac" init-method="init"/>
<bean id="settings" class="com.pep.Settings"/>

ve SomeAbac sınıfının,

@Autowired private Settings settings;

bilinmeyen bir nedenden ötürü, öğe hiç mevcut olmadığında init () 'de ayarlar null<context:component-scan/> , ancak mevcut olduğunda ve basePackage olarak bazı bs'leri olduğunda, her şey iyi çalışır. Bu çizgi şimdi şöyle görünüyor:

<context:component-scan base-package="some.shit"/>

ve çalışıyor. Birisi bir açıklama yapabilir, ama benim için şu anda yeterli)


5
Bu cevap açıklamadır. <context:component-scan/>dolaylı olarak çalışması <context:annotation-config/>için gerekli olanı sağlar @Autowired.
ForNeVeR

3

Bu NullPointerException vermek suçludur MileageFeeCalculator calc = new MileageFeeCalculator();Bahar kullanıyoruz - elle nesne oluşturmak gerekmez. Nesne oluşturma IoC konteyneri tarafından halledilecektir.


2

Ayrıca hizmet sınıfındaki @Service ek açıklamasını kullanarak ve gerekli fasulye sınıfı A'yı diğer fasulye classB yapıcısına bir parametre olarak geçirerek ve sınıfB yapıcısına @Autowired ile açıklama ekleyerek bu sorunu çözebilirsiniz. Burada snippet örneği:

@Service
public class ClassB {

    private ClassA classA;

    @Autowired
    public ClassB(ClassA classA) {
        this.classA = classA;
    }

    public void useClassAObjectHere(){
        classA.callMethodOnObjectA();
    }
}

bu benim için işe yaradı bu sorunu nasıl çözdüğünü açıklar mısınız?
CruelEngine

1
@CruelEngine, sadece alan enjeksiyonunu kullanmak yerine yapıcı enjeksiyonu (açıkça bir nesneyi ayarladığınız yer) bakın (bu çoğunlukla yay yapılandırması ile yapılır). Yani "new" operatörünü kullanarak ClassB nesnesini oluşturuyorsanız, bu ClassA için görünür veya otomatik kablolu olarak ayarlanmayacaktır. Bu nedenle, classB.useClassAObjectHere () çağrılırken, yalnızca Enjeksiyon alanını bildirirseniz classA nesnesi otomatik olarak bağlanmadığı için NPE'yi atacaktır. Chrylis de bunu açıklamaya çalışıyor. Ve bu yüzden saha enjeksiyonuna yapıcı enjeksiyonu önerilmektedir. Şimdi mantıklı mı?
Abhishek

1

Burada belirtilmemiş olanlar bu makalede "İcra emri" paragrafında açıklanmıştır .

@Component veya @Service veya @Repository türevleriyle bir sınıfa açıklama eklemem gerektiğini "öğrendikten" sonra, içlerindeki diğer bileşenleri otomatik olarak bağlamak için, bu diğer bileşenlerin hala yapıcı içinde boş olduğu bana vurdu üst bileşen.

@PostConstruct kullanmak aşağıdakileri çözer:

@SpringBootApplication
public class Application {
    @Autowired MyComponent comp;
}

ve:

@Component
public class MyComponent {
    @Autowired ComponentDAO dao;

    public MyComponent() {
        // dao is null here
    }

    @PostConstruct
    public void init() {
        // dao is initialized here
    }
}

1

Bu sadece Birim testi için geçerlidir.

Hizmet sınıfımın bir hizmet ek açıklaması vardı ve @autowiredbaşka bir bileşen sınıfıydı. Test ettiğimde bileşen sınıfı boş geliyordu. Çünkü hizmet sınıfı için nesneyi kullanaraknew

Birim testi yazıyorsanız, kullanarak nesne oluşturmadığınızdan emin olun new object(). Bunun yerine injectMock kullanın.

Bu benim sorunumu çözdü. İşte faydalı bir bağlantı


0

Ayrıca Sebebi ne olursa olsun, bir bir yöntemi yapmak, eğer unutmayın @Serviceolarak final, autowired fasulye her zaman olacaktır dan sen erişecek null.


0

Basit bir ifadeyle, bir @Autowiredalanınnull

  • SINIFININ BAHAR FASULYE DEĞİLDİR.

  • ALAN FASULYE DEĞİLDİR.


0

Tamamen soru ile ilgili değil, ancak alan enjeksiyonu boşsa, yapıcı bazlı enjeksiyon hala iyi çalışacaktır.

    private OrderingClient orderingClient;
    private Sales2Client sales2Client;
    private Settings2Client settings2Client;

    @Autowired
    public BrinkWebTool(OrderingClient orderingClient, Sales2Client sales2Client, Settings2Client settings2Client) {
        this.orderingClient = orderingClient;
        this.sales2Client = sales2Client;
        this.settings2Client = settings2Client;
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.