मैं एक स्प्रिंग बीन में संपत्ति मूल्य को कैसे इंजेक्ट कर सकता हूं जिसे एनोटेशन का उपयोग करके कॉन्फ़िगर किया गया था?


294

मेरे पास स्प्रिंग बीन्स का एक गुच्छा है जो एनोटेशन के माध्यम से क्लासपाथ से उठाया जाता है, जैसे

@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {
    // Implementation omitted
}

स्प्रिंग एक्सएमएल फ़ाइल में, प्रॉपर्टीहोल्डर धारकऑनफिगरर परिभाषित है:

<bean id="propertyConfigurer" 
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="/WEB-INF/app.properties" />
</bean> 

मैं ऊपर दिखाए गए बीन में app.properites से गुणों में से एक को इंजेक्ट करना चाहता हूं। मैं बस ऐसा कुछ नहीं कर सकता

<bean class="com.example.PersonDaoImpl">
    <property name="maxResults" value="${results.max}"/>
</bean>

क्योंकि PersonalDaoImpl स्प्रिंग XML फ़ाइल में नहीं है (इसे एनोटेशन के माध्यम से क्लासपाथ से उठाया गया है)। मुझे निम्नलिखित के रूप में मिला है:

@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {

    @Resource(name = "propertyConfigurer")
    protected void setProperties(PropertyPlaceholderConfigurer ppc) {
    // Now how do I access results.max? 
    }
}

लेकिन यह मेरे लिए स्पष्ट नहीं है कि मैं उस संपत्ति का उपयोग कैसे कर सकता हूं जिसमें मेरी दिलचस्पी है ppc?


1
मैंने अनिवार्य रूप से एक ही सवाल पूछा है, हालांकि थोड़ा अलग परिदृश्य में: stackoverflow.com/questions/310271/… । अभी तक इसका जवाब कोई नहीं दे पाया है।
स्पेंसर कोरम्स

कृपया ध्यान दें कि स्प्रिंग 3.1 के रूप में, PropertyPlaceholderConfigurerअब अनुशंसित वर्ग नहीं है। PropertySourcesPlaceholderConfigurerइसके बजाय प्राथमिकता दें । किसी भी स्थिति में, आप XML की छोटी परिभाषा का उपयोग कर सकते हैं <context:property-placeholder />
माइकल पिपेल

जवाबों:


292

आप इसे EL सपोर्ट का उपयोग करके स्प्रिंग 3 में कर सकते हैं। उदाहरण:

@Value("#{systemProperties.databaseName}")
public void setDatabaseName(String dbName) { ... }

@Value("#{strategyBean.databaseKeyGenerator}")
public void setKeyGenerator(KeyGenerator kg) { ... }

systemPropertiesएक अंतर्निहित वस्तु है और strategyBeanएक सेम नाम है।

एक और उदाहरण, जो तब काम करता है जब आप किसी Propertiesवस्तु से संपत्ति हड़पना चाहते हैं । इससे यह भी पता चलता है कि आप @Valueखेतों में आवेदन कर सकते हैं:

@Value("#{myProperties['github.oauth.clientId']}")
private String githubOauthClientId;

यहाँ एक ब्लॉग पोस्ट है जिसके बारे में मैंने थोड़ी और जानकारी के लिए लिखा है।


8
है systemPropertiesबस System.getProperties()? मुझे लगता है कि अगर मैं अपने गुणों को स्प्रिंग बीन में इंजेक्ट करना चाहता हूं, तो मुझे <bean id="appProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">उस समय से पढ़े गए मानों को किसी अन्य सेम में परिभाषित करने की आवश्यकता है जैसे कि@Value("#{appProperties.databaseName}")
Dónal

11
अधिकतम जवाब से यह सुनिश्चित करें कि आप प्लेसहोल्डर्स को $ {db.doStuff} में भी उपयोग कर सकते हैं, तो आपको PropertiesFactoryBean की आवश्यकता नहीं है, बस प्लेसहोल्डर
कॉनफिगर

9
आप उपयोग करके अपने गुणों को जोड़ सकते हैं: गुण; उदाहरण के लिए, <उपयोग: गुण आईडी = "कॉन्फ़िगरेशन" स्थान = "वर्गपथ: /spring/environment.properties" />। मूल्य कैसे प्राप्त करें, इसके लिए संपादित उत्तर देखें। (मुझे पता है कि डॉन को मदद करने में शायद बहुत देर हो चुकी है, लेकिन दूसरों को उम्मीद है कि लाभ होगा।)

2
यह केवल मेरे लिए काम करता था जब मैंने उपयोग किया था: मेरे appname-servlet.xml फ़ाइल में गुण। मेरे आवेदन में परिभाषित गुणकॉन्फ़िग्रेटर का उपयोग करनाकनेक्टटेक्स। एक्सएमएल (स्प्रिंग एमवीसी एक नहीं) काम नहीं किया।
आसफ मेसिका

थोड़ा और पढ़ने के लिए, जो इस पर कुछ विस्तार से बताता है, इस SOF प्रश्न को भी देखें: stackoverflow.com/questions/6425795/…
arcseldon

143

निजी तौर पर मुझे डॉक्स से स्प्रिंग 3.0 में यह नया तरीका पसंद है :

private @Value("${propertyName}") String propertyField;

कोई गेटर्स या सेटर नहीं!

संपत्तियों को विन्यास के माध्यम से लोड किया जा रहा है:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
      p:location="classpath:propertyFile.properties" name="propertiesBean"/>

अपने उल्लास को और बढ़ाने के लिए मैं IntelliJ में ईएल एक्सप्रेशन पर क्लिक भी नियंत्रित कर सकता हूं और यह मुझे संपत्ति की परिभाषा में लाता है!

पूरी तरह से गैर xml संस्करण भी है :

@PropertySource("classpath:propertyFile.properties")
public class AppConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

9
सुनिश्चित करें और नामस्थान में जोड़ें uri xmlns: p = " springframework.org/schema/p " p: उपसर्ग विशेषता का उपयोग करने के लिए।
शेन लीने

3
यह विधियाँ परीक्षण के संदर्भ में काम क्यों करती हैं लेकिन मुख्य संदर्भ में नहीं?
लुक्समिर

9
आह, मैंने एनोटेशन-ओनली एप्रोच वर्क बनाने की कोशिश में घंटों का समय लगाया और खोजा कि इस उत्तर को पढ़ने के बाद ही क्या याद आ रहा है- मैजिकल स्टैटिक बीन प्रॉपर्टीसैयडा यायादा की घोषणा। वसंत प्यार!
Kranach

@barrymac हे बैरी, क्या U जानते हैं कि @Value (# {...}) और @Value ($ {...}) में क्या अंतर है। धन्यवाद
किम

1
यह मेरे लिए काम करता है। केवल एक टिप: एनोटेशन @Component की आवश्यकता है।
यकी_नूका

121

स्प्रिंग 3.0.0M3@Value में एक नया एनोटेशन है । न केवल अभिव्यक्ति बल्कि प्लेसहोल्डर्स का भी समर्थन करें@Value#{...}${...}


20
+1 यदि कोई उदाहरण मदद करता है, तो वह है - @ वैल्यू (मान = "# {$ {server.env} '}") या बस @ वेल्यू ("# {$ {server.env}'}")
सोमू

31

<context:property-placeholder ... /> XML संपत्तिप्रॉप्सहोल्डरकॉन्फिगर के बराबर है।

उदाहरण: applicationContext.xml

<context:property-placeholder location="classpath:test.properties"/>  

घटक वर्ग

 private @Value("${propertyName}") String propertyField;

1
मेरे लिए, यह केवल तभी काम करता है जब ऑटोरायरिंग को <context:component-scan base-package="com.company.package" />फ़ॉर संदर्भ के माध्यम से सक्षम किया जाता है , मैं स्प्रिंग का उपयोग ApplicationContextवेब संदर्भ में नहीं, के माध्यम से करता हूं ।
मुस्तफा

15

एक और विकल्प नीचे दिखाया गया appProperties सेम जोड़ने के लिए है:

<bean id="propertyConfigurer"   
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="/WEB-INF/app.properties" />
</bean> 


<bean id="appProperties" 
          class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="singleton" value="true"/>

        <property name="properties">
                <props>
                        <prop key="results.max">${results.max}</prop>
                </props>
        </property>
</bean>

जब पुन: प्राप्त किया जाता है, तो इस बीन को कास्ट किया जा सकता है, java.util.Propertiesजिसमें एक संपत्ति होगी results.maxजिसका नाम से पढ़ा जाता है app.properties। फिर से, इस सेम को @Resource एनोटेशन के माध्यम से किसी भी वर्ग में इंजेक्शन (java.util.Properties के उदाहरण के रूप में) इंजेक्ट किया जा सकता है।

व्यक्तिगत रूप से, मैं इस समाधान को पसंद करता हूं (दूसरे को मैंने जो प्रस्तावित किया है), जैसा कि आप ठीक-ठीक बता सकते हैं कि कौन से गुण appProperties द्वारा उजागर किए गए हैं, और app.properties को दो बार पढ़ने की आवश्यकता नहीं है।


मेरे लिए भी काम करता है। लेकिन क्या प्रॉपर्टीजहोल्डरहोल्डर से संपत्तियों को ऐंठने का कोई और तरीका नहीं है @Value एनोटेशन के जरिए (जब कई कॉनफिगर XML फाइलों में मल्टीपल प्रॉपर्टीहोल्डरकॉन्फिगर का इस्तेमाल करते हैं।)।
Czar

9

मुझे दो संपत्तियों की फाइलें चाहिए, एक उत्पादन के लिए और एक विकास के लिए ओवरराइड (जो तैनात नहीं किया जाएगा)।

दोनों के लिए, एक गुण बीन, जिसे स्वत: प्राप्त किया जा सकता है और एक प्रॉपर्टीकोनिगर, आप लिख सकते हैं:

<bean id="appProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="singleton" value="true" />

    <property name="ignoreResourceNotFound" value="true" />
    <property name="locations">
        <list>
            <value>classpath:live.properties</value>
            <value>classpath:development.properties</value>
        </list>
    </property>
</bean>

और PropertyConfigurer में गुण बीन का संदर्भ दें

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="properties" ref="appProperties" />
</bean>

7

इससे पहले कि हम स्प्रिंग 3 प्राप्त करें - जो आपको एनोटेशन का उपयोग करके सीधे अपने बीन्स में संपत्ति स्थिरांक इंजेक्ट करने की अनुमति देता है - मैंने प्रॉपर्टीप्लेहोल्डरकॉन्फिगर बीन का एक उप-वर्ग लिखा था जो समान काम करता है। तो, आप अपनी संपत्ति बसाने वालों को चिन्हित कर सकते हैं और वसंत आपकी संपत्तियों को अपनी फलियों में इस तरह उतारेगा:

@Property(key="property.key", defaultValue="default")
public void setProperty(String property) {
    this.property = property;
}

एनोटेशन इस प्रकार है:

@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface Property {
    String key();
    String defaultValue() default "";
}

प्रॉपर्टीअनोटेशनएंडप्लसधारकसंपर्ककर्ता इस प्रकार है:

public class PropertyAnnotationAndPlaceholderConfigurer extends PropertyPlaceholderConfigurer {

    private static Logger log = Logger.getLogger(PropertyAnnotationAndPlaceholderConfigurer.class);

    @Override
    protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties properties) throws BeansException {
        super.processProperties(beanFactory, properties);

        for (String name : beanFactory.getBeanDefinitionNames()) {
            MutablePropertyValues mpv = beanFactory.getBeanDefinition(name).getPropertyValues();
            Class clazz = beanFactory.getType(name);

            if(log.isDebugEnabled()) log.debug("Configuring properties for bean="+name+"["+clazz+"]");

            if(clazz != null) {
                for (PropertyDescriptor property : BeanUtils.getPropertyDescriptors(clazz)) {
                    Method setter = property.getWriteMethod();
                    Method getter = property.getReadMethod();
                    Property annotation = null;
                    if(setter != null && setter.isAnnotationPresent(Property.class)) {
                        annotation = setter.getAnnotation(Property.class);
                    } else if(setter != null && getter != null && getter.isAnnotationPresent(Property.class)) {
                        annotation = getter.getAnnotation(Property.class);
                    }
                    if(annotation != null) {
                        String value = resolvePlaceholder(annotation.key(), properties, SYSTEM_PROPERTIES_MODE_FALLBACK);
                        if(StringUtils.isEmpty(value)) {
                            value = annotation.defaultValue();
                        }
                        if(StringUtils.isEmpty(value)) {
                            throw new BeanConfigurationException("No such property=["+annotation.key()+"] found in properties.");
                        }
                        if(log.isDebugEnabled()) log.debug("setting property=["+clazz.getName()+"."+property.getName()+"] value=["+annotation.key()+"="+value+"]");
                        mpv.addPropertyValue(property.getName(), value);
                    }
                }

                for(Field field : clazz.getDeclaredFields()) {
                    if(log.isDebugEnabled()) log.debug("examining field=["+clazz.getName()+"."+field.getName()+"]");
                    if(field.isAnnotationPresent(Property.class)) {
                        Property annotation = field.getAnnotation(Property.class);
                        PropertyDescriptor property = BeanUtils.getPropertyDescriptor(clazz, field.getName());

                        if(property.getWriteMethod() == null) {
                            throw new BeanConfigurationException("setter for property=["+clazz.getName()+"."+field.getName()+"] not available.");
                        }

                        Object value = resolvePlaceholder(annotation.key(), properties, SYSTEM_PROPERTIES_MODE_FALLBACK);
                        if(value == null) {
                            value = annotation.defaultValue();
                        }
                        if(value == null) {
                            throw new BeanConfigurationException("No such property=["+annotation.key()+"] found in properties.");
                        }
                        if(log.isDebugEnabled()) log.debug("setting property=["+clazz.getName()+"."+field.getName()+"] value=["+annotation.key()+"="+value+"]");
                        mpv.addPropertyValue(property.getName(), value);
                    }
                }
            }
        }
    }

}

स्वाद के लिए संशोधित करने के लिए स्वतंत्र महसूस करें


3
कृपया ध्यान दें, मैं के लिए ऊपर एक नई परियोजना बनाई है, जिसे: code.google.com/p/spring-property-annotations
रिकार्डो ग्लैडवेल

7

आप भी आपको वर्ग का एनोटेट कर सकते हैं:

@PropertySource("classpath:/com/myProject/config/properties/database.properties")

और इस तरह एक चर है:

@Autowired
private Environment env;

अब आप इस तरह से अपनी सभी संपत्तियों तक पहुँच सकते हैं:

env.getProperty("database.connection.driver")

7

वसंत रास्ता:
private @Value("${propertyName}") String propertyField;

स्प्रिंग के "प्रॉपर्टीप्लेहोल्डरकॉन्फिगर" वर्ग का उपयोग करके मूल्य को इंजेक्ट करने का एक नया तरीका है। दूसरा तरीका है कॉल करना

java.util.Properties props = System.getProperties().getProperty("propertyName");

नोट: @Value के लिए, आप स्थैतिक संपत्ति का उपयोग नहीं कर सकते हैं, यह केवल गैर-स्थिर होना चाहिए, अन्यथा यह अशक्त हो जाता है। इसे ठीक करने के लिए एक स्थैतिक क्षेत्र के लिए एक गैर स्थिर सेटर बनाया जाता है और उस सेटर के ऊपर @Value लगाया जाता है।


7

जैसा कि उल्लेख किया गया @Valueहै यह काम करता है और यह काफी लचीला है क्योंकि आप इसमें स्प्रिंग ईएल रख सकते हैं।

यहां कुछ उदाहरण दिए गए हैं, जो मददगार हो सकते हैं:

//Build and array from comma separated parameters 
//Like currency.codes.list=10,11,12,13
@Value("#{'${currency.codes.list}'.split(',')}") 
private List<String> currencyTypes;

एक से प्राप्त करने के लिए एक setऔरlist

//If you have a list of some objects like (List<BranchVO>) 
//and the BranchVO has areaCode,cityCode,...
//You can easily make a set or areaCodes as below
@Value("#{BranchList.![areaCode]}") 
private Set<String> areas;

आप आदिम प्रकारों के लिए मान भी सेट कर सकते हैं।

@Value("${amount.limit}")
private int amountLimit;

आप स्थैतिक तरीकों को कॉल कर सकते हैं:

@Value("#{T(foo.bar).isSecurityEnabled()}")
private boolean securityEnabled;

आपके पास तर्क हो सकते हैं

@Value("#{T(foo.bar).isSecurityEnabled() ? '${security.logo.path}' : '${default.logo.path}'}")
private String logoPath;

5

एक संभावित समाधान दूसरा बीन घोषित करना है जो समान गुण फ़ाइल से पढ़ता है:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="/WEB-INF/app.properties" />
</bean> 

<util:properties id="appProperties" location="classpath:/WEB-INF/app.properties"/>

'AppProperties' नाम का बीन java.util.Properties का प्रकार है और यह ऊपर दिखाए गए @Resource एट्रिब्यूट का उपयोग करके निर्भरता इंजेक्ट किया जा सकता है।


4

यदि आप स्प्रिंग 2.5 का उपयोग कर रहे हैं, तो आप अपने प्रत्येक गुण के लिए सेम को परिभाषित कर सकते हैं और क्वालिफायर का उपयोग करके उन्हें इंजेक्ट कर सकते हैं। ऐशे ही:

  <bean id="someFile" class="java.io.File">
    <constructor-arg value="${someFile}"/>
  </bean>

तथा

@Service
public class Thing
      public Thing(@Qualifier("someFile") File someFile) {
...

यह सुपर पठनीय नहीं है, लेकिन यह काम हो जाता है।


2

स्प्रिंग बीन्स में स्वत: संपत्तियों का मूल्य:

ज्यादातर लोग जानते हैं कि जब आप अपने एप्लिकेशन संदर्भ को लोड करते हैं तो आप किसी वस्तु को दूसरे में इंजेक्ट करने के लिए स्प्रिंग को बताने के लिए @Autowired का उपयोग कर सकते हैं। जानकारी की एक कम ज्ञात डली यह है कि आप संपत्ति फ़ाइल से मानों को बीन के गुणों में इंजेक्ट करने के लिए @ वेल्यू एनोटेशन का भी उपयोग कर सकते हैं। अधिक जानकारी के लिए इस पोस्ट को देखें ...

स्प्रिंग 3.0 में नया सामान || ऑटोबायरिंग बीन मान || वसंत में संपत्ति मूल्यों को प्राप्त करना


2

मेरे लिए, यह @ लकी का जवाब था, और विशेष रूप से, लाइन

AutowiredFakaSource fakeDataSource = ctx.getBean(AutowiredFakaSource.class);

से कप्तान डीबग पेज

मेरी समस्या ठीक हो गई। मेरे पास एक ApplicationContext- आधारित ऐप है, जो कमांड-लाइन से चल रहा है, और एसओ पर कई टिप्पणियों को देखते हुए, स्प्रिंग इन एमवीसी-आधारित ऐप के लिए अलग तरीके से वायर करते हैं।


1

मुझे लगता है कि सेम में गुणों को इंजेक्ट करने का यह सबसे सुविधाजनक तरीका है।

उदाहरण:

package org.some.beans;

public class MyBean {
    Long id;
    String name;

    public void setId(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

बीन xml परिभाषा:

<bean id="Bean1" class="org.some.beans.MyBean">
    <property name="id" value="1"/>
    <property name="name" value="MyBean"/>
</bean>

प्रत्येक नामित propertyविधि के setProperty(value)लिए आमंत्रित किया जाएगा।

यह तरीका विशेष रूप से सहायक है यदि आपको एक कार्यान्वयन के आधार पर एक से अधिक सेम की आवश्यकता है।

उदाहरण के लिए, यदि हम xml में एक और बीन को परिभाषित करते हैं:

<bean id="Bean2" class="org.some.beans.MyBean">
    <property name="id" value="2"/>
    <property name="name" value="EnotherBean"/>
</bean>

फिर इस तरह कोड:

MyBean b1 = appContext.getBean("Bean1");
System.out.println("Bean id = " + b1.getId() + " name = " + b1.getName());
MyBean b2 = appContext.getBean("Bean2");
System.out.println("Bean id = " + b2.getId() + " name = " + b2.getName());

छपेगा

Bean id = 1 name = MyBean
Bean id = 2 name = AnotherBean

तो, आपके मामले में यह इस तरह दिखना चाहिए:

@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {

    Long maxResults;

    public void setMaxResults(Long maxResults) {
        this.maxResults = maxResults;
    }

    // Now use maxResults value in your code, it will be injected on Bean creation
    public void someMethod(Long results) {
        if (results < maxResults) {
            ...
        }
    }
}

0

यदि आपको कॉन्फ़िगरेशन के लिए अधिक लचीलापन चाहिए, तो Settings4jPlaceholderConfigurer का प्रयास करें: http://settings4j.sourceforge.net/currentrelease/configSpringPlaceholder.html

हमारे आवेदन में हम उपयोग करते हैं:

  • PreProd- और प्रोडक्ट-सिस्टम को कॉन्फ़िगर करने के लिए प्राथमिकताएं
  • वरीयताएँ और JNDI पर्यावरण चर (JNDI वरीयताएँ अधिलेखित करता है) "mvan jetty: run" के लिए
  • UnitTests के लिए सिस्टम गुण (@BeforeClass एनोटेशन)

डिफ़ॉल्ट ऑर्डर जिसे की-वैल्यू-सोर्स सबसे पहले चेक किया जाता है, उसमें वर्णित है:
http://settings4j.sourceforge.net/currentrelease/configDefault.html
यह आपके द्वारा settings4j.xml (log4j.xml के लिए सटीक) के साथ अनुकूलित किया जा सकता है classpath।

मुझे अपनी राय बताएं: settings4j-user@lists.sourceforge.net

मैत्रीपूर्ण संबंध के साथ,
हैराल्ड


-1

स्प्रिंग के "प्रॉपर्टीप्लेहोल्डरकॉन्फिगर" वर्ग का उपयोग करें

संपत्ति फ़ाइल को दिखाने का एक सरल उदाहरण गतिशील रूप से सेम की संपत्ति के रूप में पढ़ा जाता है

<bean id="placeholderConfig"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>/WEB-INF/classes/config_properties/dev/database.properties</value>
        </list>
    </property> 
</bean>

<bean id="devDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${dev.app.jdbc.driver}"/>
    <property name="jdbcUrl" value="${dev.app.jdbc.url}"/>
    <property name="user" value="${dev.app.jdbc.username}"/>
    <property name="password" value="${dev.app.jdbc.password}"/>
    <property name="acquireIncrement" value="3"/>
    <property name="minPoolSize" value="5"/>
    <property name="maxPoolSize" value="10"/>
    <property name="maxStatementsPerConnection" value="11000"/>
    <property name="numHelperThreads" value="8"/>
    <property name="idleConnectionTestPeriod" value="300"/>
    <property name="preferredTestQuery" value="SELECT 0"/>
</bean> 

संपत्ति फ़ाइल

dev.app.jdbc.driver = com.mysql.jdbc.Driver

dev.app.jdbc.url = JDBC: mysql: // स्थानीय होस्ट: 3306 / addvertisement

dev.app.jdbc.username = जड़

dev.app.jdbc.password = जड़

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.