ฉันจะฉีดค่าคุณสมบัติลงใน Spring Bean ซึ่งกำหนดค่าโดยใช้คำอธิบายประกอบได้อย่างไร


294

ฉันมีถั่วสปริงจำนวนหนึ่งซึ่งหยิบขึ้นมาจาก classpath ผ่านคำอธิบายประกอบเช่น

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

ในไฟล์ Spring XML มีการกำหนดPropertyPlaceholderConfigurer :

<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>

เนื่องจาก PersonDaoImpl ไม่มีคุณสมบัติในไฟล์ Spring XML (ถูกดึงจาก classpath ผ่านคำอธิบายประกอบ) ฉันได้เท่าที่ต่อไปนี้:

@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/... จนถึงขณะนี้ยังไม่มีใครสามารถตอบได้
Spencer Kormos

โปรดทราบว่าตั้งแต่ฤดูใบไม้ผลิ 3.1 PropertyPlaceholderConfigurerไม่ใช่คลาสที่แนะนำอีกต่อไป ชอบPropertySourcesPlaceholderConfigurerมากกว่า ในกรณีใด ๆ คุณสามารถใช้ XML <context:property-placeholder />นิยามสั้น
Michael Piefel

คำตอบ:


292

คุณสามารถทำได้ใน Spring 3 โดยใช้การสนับสนุน EL ตัวอย่าง:

@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
ตรวจสอบให้แน่ใจว่าได้รับคำตอบจากคำตอบของ max ที่คุณสามารถใช้ placeholder ในนิพจน์ $ {db.doStuff} จากนั้นคุณไม่จำเป็นต้องมี PropertiesFactoryBean เพียงแค่ placeholderConfigurer
gtrak

9
คุณสามารถเพิ่มคุณสมบัติของคุณเองโดยใช้ util: properties; เช่น <util: properties id = "config" location = "classpath: /spring/environment.properties" /> ดูคำตอบที่แก้ไขแล้วสำหรับวิธีรับค่า (ฉันรู้ว่านี่อาจจะสายเกินไปที่จะช่วย Don ได้ แต่คนอื่น ๆ ก็หวังว่าจะได้รับประโยชน์)

2
มันใช้งานได้สำหรับฉันเมื่อฉันใช้ util: properties ในไฟล์ appname-servlet.xml การใช้ propertyConfigurer ที่กำหนดใน applicationContext.xml ของฉัน (ไม่ใช่ Spring MVC) ไม่ทำงาน
Asaf Mesika

สำหรับการอ่านเพิ่มเติมเล็กน้อยที่ให้รายละเอียดเกี่ยวกับเรื่องนี้ลองดูคำถาม SOF เช่นกัน: stackoverflow.com/questions/6425795/…
arcseldon

143

โดยส่วนตัวฉันชอบวิธีใหม่นี้ใน Spring 3.0 จากเอกสาร :

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

ไม่มีผู้ได้รับหรือผู้ตั้งค่า!

ด้วยคุณสมบัติที่กำลังโหลดผ่านการกำหนดค่า:

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

เพื่อเพิ่มเติมความยินดีของฉันฉันสามารถควบคุมการคลิกที่นิพจน์ EL ใน 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: คำนำหน้า
shane lee

3
เหตุใดวิธีการนี้จึงใช้งานได้ในบริบททดสอบ แต่ไม่ใช่ในบริบทหลัก
luksmir

9
ถอนหายใจฉันใช้เวลาหลายชั่วโมงในการพยายามทำหมายเหตุประกอบอย่างเดียวทำงานและค้นพบสิ่งที่ขาดหายไปหลังจากอ่านคำตอบนี้ - ประกาศของถั่วคงวิเศษ PropertySauceYadaYada รักฤดูใบไม้ผลิ!
Kranach

@barrymac เฮ้แบร์รี่ทำคุณรู้ว่าอะไรคือความแตกต่างระหว่าง @Value (# {... }) และ @Value ($ {... }) ขอบคุณ
Kim

1
มันใช้งานได้สำหรับฉัน เคล็ดลับเดียวเท่านั้น: จำเป็นต้องมีคำอธิบายประกอบ @Component
yaki_nuka

121

มีคำอธิบายประกอบใหม่คือ@Valueในฤดูใบไม้ผลิ 3.0.0M3 @Valueสนับสนุนการ#{...}แสดงออกไม่เพียงแต่${...}ตัวยึดตำแหน่งเช่นกัน


20
+1 หากตัวอย่างช่วยนี่คือ - @Value (value = "# {'$ {server.env}'}") หรือเพียงแค่ @Value ("# {'$ {server.env}'}"
Somu

31

<context:property-placeholder ... /> เป็น XML ที่เทียบเท่ากับ PropertyPlaceholderConfigurer

ตัวอย่าง: 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 ที่แสดงด้านล่าง:

<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อีกครั้งถั่วนี้สามารถถูกฉีดพึ่งพา (เป็นตัวอย่างของ java.util.Properties) ลงในคลาสใด ๆ ผ่านทางหมายเหตุประกอบ @Resource

โดยส่วนตัวแล้วฉันชอบโซลูชันนี้ (ตามที่ฉันเสนออื่น ๆ ) เนื่องจากคุณสามารถ จำกัด คุณสมบัติที่ appProperties ต้องเปิดเผยและไม่จำเป็นต้องอ่าน app.properties สองครั้ง


ได้ผลสำหรับฉันเช่นกัน แต่ไม่มีวิธีอื่นในการ acces คุณสมบัติจาก PropertyPlaceholderConfigurer ผ่านทางหมายเหตุประกอบ @Value (เมื่อใช้หลาย PropertyPlaceholderConfigurer ในไฟล์ XML congif หลายไฟล์)?
จักรพรรดิ

9

ฉันต้องมีไฟล์คุณสมบัติสองไฟล์หนึ่งไฟล์สำหรับการผลิตและการแทนที่สำหรับการพัฒนา (ที่จะไม่ถูกปรับใช้)

ในการมีทั้ง Properties Bean ที่สามารถ autowired และ PropertyConfigurer คุณสามารถเขียน:

<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>

และอ้างอิง Properties Bean ใน PropertyConfigurer

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

7

ก่อนที่เราจะได้ Spring 3 - ซึ่งอนุญาตให้คุณฉีดค่าคงที่ของคุณสมบัติลงในถั่วของคุณโดยตรงโดยใช้คำอธิบายประกอบ - ฉันเขียนคลาสย่อยของ PropertyPlaceholderConfigurer bean ที่ทำสิ่งเดียวกัน ดังนั้นคุณสามารถทำเครื่องหมายที่ตัวตั้งค่าคุณสมบัติของคุณและสปริงจะทำให้คุณสมบัติของคุณเป็นถั่วอัตโนมัติ:

@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 "";
}

PropertyAnnotationAndPlaceholderConfigurer เป็นดังนี้:

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
Ricardo Gladwell

7

คุณยังสามารถใส่คำอธิบายประกอบในชั้นเรียนของคุณ:

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

และมีตัวแปรเช่นนี้

@Autowired
private Environment env;

ตอนนี้คุณสามารถเข้าถึงคุณสมบัติทั้งหมดของคุณด้วยวิธีนี้:

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

7

ทางสปริง:
private @Value("${propertyName}") String propertyField;

เป็นวิธีใหม่ในการฉีดค่าโดยใช้คลาส "PropertyPlaceholderConfigurer" ของ Spring อีกวิธีคือการโทร

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

หมายเหตุ: สำหรับ @Value คุณไม่สามารถใช้static propertyField ได้ซึ่งควรเป็นแบบไม่คงที่เท่านั้นมิฉะนั้นจะส่งคืนค่า null หากต้องการแก้ไขมันตัวตั้งค่าแบบคงที่จะถูกสร้างขึ้นสำหรับเขตข้อมูลแบบคงที่และใช้ @Value เหนือตัวตั้งค่านั้น


7

ตามที่กล่าวไว้ @Valueทำงานและมีความยืดหยุ่นมากเพราะคุณสามารถใช้สปริง EL ได้

นี่คือตัวอย่างบางส่วนซึ่งอาจเป็นประโยชน์:

//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 ตัวที่สองซึ่งอ่านจากไฟล์คุณสมบัติเดียวกัน:

<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"/>

bean ชื่อ 'appProperties' เป็นประเภท java.util.Properties และสามารถฉีดขึ้นต่อกันได้โดยใช้ @Resource attruibute ที่แสดงด้านบน


4

หากคุณติดขัดในการใช้ Spring 2.5 คุณสามารถกำหนด bean สำหรับคุณสมบัติแต่ละรายการของคุณและฉีดโดยใช้ qualifier แบบนี้:

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

และ

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

มันไม่สามารถอ่านได้สุด แต่ได้รับงานทำ


2

การกำหนดค่าคุณสมบัติอัตโนมัติในถั่วสปริง:

คนส่วนใหญ่รู้ว่าคุณสามารถใช้ @Autowired เพื่อบอก Spring ให้ส่งวัตถุหนึ่งไปยังอีกวัตถุหนึ่งเมื่อโหลดบริบทแอปพลิเคชันของคุณ ข้อมูลที่รู้จักกันน้อยกว่าก็คือคุณสามารถใช้คำอธิบายประกอบ @Value เพื่อฉีดค่าจากไฟล์คุณสมบัติลงในแอตทริบิวต์ของ bean ดูโพสต์นี้สำหรับข้อมูลเพิ่มเติม ...

สิ่งใหม่ใน Spring 3.0 || autowiring ค่าถั่ว || การเรียกค่าคุณสมบัติอัตโนมัติในฤดูใบไม้ผลิ


2

สำหรับฉันมันเป็นคำตอบของ @ Lucky และโดยเฉพาะอย่างยิ่งสาย

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

จากหน้ากัปตันดีบั๊ก

ที่แก้ไขปัญหาของฉัน ฉันมีแอพพลิเคชั่นที่ใช้ ApplicationContext ทำงานจากบรรทัดคำสั่งและตัดสินจากความคิดเห็นจำนวนหนึ่งเกี่ยวกับ SO สปริงจะเชื่อมโยงแอปที่ใช้ MVC เหล่านี้แตกต่างกัน


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- และ Prod-System
  • การกำหนดค่าตามความชอบและตัวแปร JNDI Environment (JNDI เขียนทับการกำหนดค่าตามความชอบ) สำหรับ "mvn jetty: run"
  • คุณสมบัติของระบบสำหรับ UnitTests (คำอธิบายประกอบ @BeforeClass)

ลำดับเริ่มต้นซึ่งมีการตรวจสอบคีย์ - ค่า - ซอร์สก่อนอธิบายไว้ใน:
http://settings4j.sourceforge.net/currentrelease/configDefault.html
ซึ่งสามารถกำหนดค่าได้ด้วย settings4j.xml (ถูกต้องถึง log4j.xml) ในของคุณ classpath

แจ้งให้เราทราบความคิดเห็นของคุณ: settings4j-user@lists.sourceforge.net

ด้วยความนับถือ
Harald


-1

ใช้คลาส "PropertyPlaceholderConfigurer" ของ Spring

ตัวอย่างง่ายๆที่แสดงไฟล์คุณสมบัติอ่านแบบไดนามิกเป็นคุณสมบัติของ bean

<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: // localhost: 3306 / addvertisement

dev.app.jdbc.username = ราก

dev.app.jdbc.password = ราก

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