Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
ʹÓÃSpringBoot¿ªÆô΢·þÎñÖ®ÂÃ
 
  6130  次浏览      27
 2018-1-23
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚVictor Grazi £¬±¾ÎĽ«ÑÝʾʹÓÃConsul·þÎñ×¢²áÖÐÐĺÍSpring Boot´î½¨¸÷ÖÖ½ÅÊּܡ¢½øÐÐÒÀÀµ×¢ÈëºÍÒÀÀµ¹ÜÀí£¬Ê¹ÓÃMaven½øÐй¹½¨£¬Ê¹ÓÃSpring RESTºÍJersey/JaxRS´´½¨Java REST·ç¸ñAPI¡£

Èç¹û»¹Ã»ÓÐ×¼±¸ºÃʹÓÃ΢·þÎñ£¬ÄÇÄã¿Ï¶¨ÂäºóÓÚѧϰÇúÏßÖеÄÔçÆÚ½ÓÊÜÕß½×¶ÎÁË£¬¶øÇÒÊÇʱºò¿ªÆô΢·þÎñÖ®ÂÃÁË¡£±¾ÎÄÖУ¬ÎÒÃǽ«ÑÝʾ´´½¨REST·ç¸ñ΢·þÎñËù±ØÐèµÄ¸÷ÖÖ×é¼þ£¬Ê¹ÓÃConsul·þÎñ×¢²áÖÐÐĺÍSpring Boot´î½¨¸÷ÖÖ½ÅÊּܡ¢½øÐÐÒÀÀµ×¢ÈëºÍÒÀÀµ¹ÜÀí£¬Ê¹ÓÃMaven½øÐй¹½¨£¬Ê¹ÓÃSpring RESTºÍJersey/JaxRS´´½¨Java REST·ç¸ñAPI¡£

ÔÚ¹ýÈ¥µÄ¶þÊ®ÄêÀÆóҵʹÓÃSDLCÁ÷³Ì±äµÃ·Ç³£Ãô½Ý£¬µ«ÊÇÓ¦ÓóÌÐòÈÔÈ»Ï൱ÅÓ´ó¶øÇÒñîºÏÔÚÒ»Æð£¬°üº¬´óÁ¿Ö§³Ö¸÷ÖÖ°æ±¾µÄ¸÷ÖÖ¸÷ÑùAPIµÄjar°ü¡£µ«ÊÇ£¬Èç½ñÓÐÒ»ÖÖÇ÷ÊÆ³¯×Ÿü¾«¼òµÄDevOps·¶µÄÁ÷³ÌÍÆ½ø£¬¹¦ÄÜÒ²±äµÃ¡°ÎÞ·þÎñÆ÷»¯¡±¡£½øÐÐ΢·þÎñÖØ¹¹¿ÉÒÔ½âñî´úÂëºÍ×ÊÔ´£¬Èù¹½¨Á÷³Ì¸üС£¬È÷¢²¼¸ü°²È«£¬ÈÃAPI¸üÎȶ¨¡£

±¾ÎÄÖУ¬ÎÒÃǽ«¹¹½¨Ò»¸ö¼òÒ׵Ĺɯ±Êг¡Í¶×Ê×éºÏ¹ÜÀíÓ¦ÓóÌÐò¡£ÔÚÕâ¸öÓ¦ÓÃÖУ¬¿Í»§¿ÉÒÔͨ¹ý·þÎñµ÷Óã¬ÎªËûÃÇµÄ¹ÉÆ±Í¶×Ê×éºÏ£¨¹ÉƱ´úÂëºÍÊýÁ¿£©½øÐж¨¼Û¡£Í¶×Ê×éºÏ΢·þÎñ½«¼ìË÷Óû§µÄͶ×Ê×éºÏ£¬½«Ëü·¢Ë͸ø¶¨¼Û΢·þÎñÀ´Ó¦ÓÃ×îÐµĶ¨¼Û£¬È»ºó·µ»ØÍêÈ«¶¨¼ÛºÍ·ÖÀà»ã×ܹýµÄͶ×Ê×éºÏ£¬Í¨¹ýÒ»¸öRESTµ÷Óý«ËùÓÐÕâЩÐÅϢչʾ¸ø¿Í»§¡£

ÔÚÎÒÃÇ¿ªÊ¼´´½¨Î¢·þÎñ֮ǰ£¬ÐèÒª°²×°ConsulÀ´×¼±¸ÎÒÃǵĻ·¾³¡£

ÏÂÔØConsul·þÎñ×¢²áÖÐÐÄ

ÎÒÃǽ«Ê¹ÓÃHashicorp ConsulÀ´ÊµÏÖ·þÎñ·¢ÏÖ£¬ËùÒÔÇëǰÍù https://www.consul.io/downloads.html ÏÂÔØConsul£¬ÓÐWindows°æ¡¢Linux°æºÍMac°æµÈ¡£Õâ¸öÁ´½Ó½«»áÌṩһ¸ö¿ÉÖ´ÐгÌÐò£¬ÄãÐèÒª½«Õâ¸ö³ÌÐòÌí¼Óµ½ÄãµÄpath»·¾³±äÁ¿ÖС£

Æô¶¯Consul

´ÓÒ»¸ö½Å±¾µ¯³ö¿òÒÔdevģʽÆô¶¯Consul£º

consul agent -dev

ΪÁËÑéÖ¤ËüȷʵÒѾ­ÔÚÔËÐУ¬¿ÉÒÔ´ò¿ªä¯ÀÀÆ÷£¬·ÃÎÊconsul UI http://localhost:8500 ¡£Èç¹ûÒ»ÇÐÕý³££¬consulÓ¦¸Ã»á±¨¸æËüµÄÔËÐÐ״̬Á¼ºÃ¡£µã»÷£¨ÔÚ×ó±ßµÄ£©consul·þÎñ£¬»á£¨ÔÚÓұߣ©Ìṩ¸ü¶àÐÅÏ¢¡£

Èç¹ûÕâ¸öµØ·½ÓÐʲôÎÊÌ⣬ÇëÈ·±£ÄãÒѾ­½«consulÌí¼Óµ½Ö´Ðз¾¶ÖжøÇÒ8500ºÍ8600¶Ë¿ÚÊÇ¿ÉÓõġ£

´´½¨SpringBootÓ¦ÓóÌÐò

ÎÒÃǽ«Ê¹Óü¯³ÉÔÚÖ÷Á÷IDEÖеÄSpring Initializr£¨https://start.spring.io/£©£¬À´´´½¨ÎÒÃǵÄSpringBootÓ¦ÓóÌÐòµÄ½ÅÊּܡ£ÏÂÃæµÄ½ØÆÁʹÓõÄÊÇIntelliJ IDEA¡£

Ñ¡ÔñFile/New Project£¬À´´ò¿ªÐ½¨ÏîĿģ°åµ¯³ö¿ò£¬È»ºóÑ¡ÔñSpring Initializr¡£

ÊÂʵÉÏ£¬Äã¿ÉÒÔÎÞÐèIDE¾Í°²×°½ÅÊּܡ£Í¨¹ýSpringBoot InitializrÍøÕ¾ https://start.spring.io Íê³ÉÒ»¸öÔÚÏßweb±í¸ñ£¬»á²ú³öÒ»¸ö¿ÉÒÔÏÂÔØµÄ°üº¬ÄãµÄ¿ÕÏîÄ¿µÄzipÎļþ¡£

µã»÷¡°Next¡±°´Å¥£¬ÌîдËùÓеÄÏîĿԪÊý¾Ý¡£Ê¹ÓÃÏÂÃæµÄÅäÖãº

µã»÷¡°Next¡±°´Å¥À´Ñ¡ÔñÒÀÀµ£¬È»ºóÔÚÒÀÀµËÑË÷À¸ÊäÈëJerseyºÍConsul Discovery¡£Ìí¼ÓÄÇЩÒÀÀµ£º

µã»÷¡°Next¡°°´Å¥À´Ö¸¶¨ÄãµÄÏîÄ¿Ãû×ֺʹæ·ÅλÖá£Ê¹ÓÃÔÚweb±íµ¥ÖÐÅäÖõÄĬÈÏÃû×Ö¡°portfolio¡±£¬Ö¸¶¨ÄãÏ£Íû´æ·ÅÏîÄ¿µÄµØÖ·£¬È»ºóµã»÷¡°Finish¡±À´Éú³É²¢´ò¿ªÏîÄ¿£º

Äã¿ÉÒÔʹÓÃÉú³ÉµÄapplication.propertiesÎļþ£¬µ«ÊÇSpringBootÒ²½ÓÊÜYAMLÎļþ¸ñʽ£¬YAML¸ñʽ¿´ÆðÀ´¸üÖ±¹Û£¬Òò´Ë¿ÉÒÔ½«Õâ¸öÎļþÖØÃüÃûΪapplication.yml¡£

ÎÒÃǽ«Õâ¸ö΢·þÎñÃüÃûΪ¡°portfolio-service¡±¡£ÎÒÃÇ¿ÉÒÔÖ¸¶¨Ò»¸ö¶Ë¿Ú»òÕßʹÓö˿Ú0À´ÈÃÓ¦ÓóÌÐòʹÓÃÒ»¸ö¿ÉÓõĶ˿ڡ£ÔÚÎÒÃǵÄÀý×ÓÖУ¬ÎÒÃÇʹÓö˿Ú57116¡£Èç¹ûÄ㽫Õâ¸ö·þÎñ×÷Ϊһ¸öDocker container²¿Êð£¬Äã¿ÉÒÔ½«ËüÓ³Éäµ½ÈκÎÄãÑ¡ÖеĶ˿ڡ£ÈÃÎÒÃÇͨ¹ýÌí¼ÓÈçÏÂÅäÖõ½applicatin.ymlÎļþ£¬À´ÎªÓ¦ÓóÌÐòÃüÃû²¢Ö¸¶¨¶Ë¿Ú£º

spring:
application:
name: portfolio-service
server:
port: 57116

ΪÁËÈÃÎÒÃǵķþÎñ¿ÉÒÔ±»·¢ÏÖ£¬ÐèҪΪSpringBootµÄapplicationÀàÌí¼Ó×¢½â¡£´ò¿ªPortfolioApplication£¬ÔÚÕâ¸öÀàÉùÃ÷µÄÉÏ·½Ìí¼Ó@EnableDiscoveryClient¡£

½ÓÊÜimports¡£Õâ¸öclass¿´ÆðÀ´»áÊÇÕâÑù£º

package com.restms.demo.portfolio;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
. . .
@SpringBootApplication
@EnableDiscoveryClient
public class PortfolioApplication {
public static void main(String[] args) {
SpringApplication.run(PortfolioApplication.class, args);
}
}

£¨ÎªÁËÑÝʾÈçºÎÓɸ÷ÖÖ¶ÀÁ¢µÄƽ̨×éºÏ΢·þÎñ£¬ÎÒÃǽ«ÎªÕâ¸ö·þÎñʹÓÃJersey£¬È»ºóΪÏÂÒ»·þÎñʹÓÃSpring REST£©¡£

ΪÁ˰²×°Jersey REST·ç¸ñWeb Service£¬ÎÒÃÇÐèÒªÖ¸¶¨Ò»¸öResourceConfig ConfigurationÀà¡£Ôö¼ÓJerseyConfigÀࣨ±¾ÀýÖУ¬ÎÒÃÇ»á°ÑËü·ÅÔÚÏàͬµÄpackageÏÂ×÷ΪÎÒÃǵÄapplicationÀà¡££©ËüÓ¦¸Ã¿´ÆðÀ´ÏñÕâÑù£¬¼ÓÉÏÊʵ±µÄpackageºÍimports£º

@Configuration
@ApplicationPath("portfolios")
public class JerseyConfig extends ResourceConfig {
public JerseyConfig()
{
register(PortfolioImpl.class);
}
}

ÐèҪעÒâµÄÊÇ£¬Ëü¼Ì³ÐÁËResourceConfigÀ´±íÃ÷ËüÊÇÒ»¸öJerseyµÄÅäÖÃÀà¡£@ApplicationPath("portfolios")ÊôÐÔÖ¸¶¨Á˵÷ÓõÄÉÏÏÂÎÄ£¬Òâζ×ŵ÷Ó÷¾¶Ó¦¸ÃÒÔ¡°portfolios¡±¿ªÍ·¡££¨Èç¹ûÄãûÓÐÖ¸¶¨£¬ÉÏÏÂÎÄĬÈÏΪ¡°/¡±¡££©

PortfolioImplÀཫ·þÎñÁ½ÖÖÇëÇ󣬯äÖÐportfolios/customer/{customer-id}·µ»ØËùÓеÄportfolios£¬¶øportfolios/customer/{customer-id}/portfolio/{portfolio-id}·µ»ØÒ»¸öportfolio¡£Ò»¸öportfolio°üÀ¨Ò»×é¹ÉƱ´úÂëºÍÏàÓ¦µÄ³ÖÓзݶ

£¨±¾ÀýÖУ¬ÓÐ3¸ö¿Í»§£¬id·Ö±ðΪ0¡¢1¡¢2£¬¶øÇÒÿһ¸ö¿Í»§¶¼ÓÐ3¸öportfolio£¬id·Ö±ðΪ0¡¢1¡¢2£©¡£

ÄãµÄIDE»áÈÃÄã´´½¨PortfolioImpl£¬ÕÕ×Å×ö¾ÍÐÐÁË¡£±¾ÀýÖУ¬½«ËüÌí¼ÓÔÚÏàͬµÄpackage¡£ÊäÈëÈçÏ´úÂë²¢½ÓÊÜËùÓÐimports£º

@Component
@Path("/portfolios")
public class PortfolioImpl implements InitializingBean {
private Object[][][][] clientPortfolios;
@GET
@Path("customer/{customer-id}")
@Produces(MediaType.APPLICATION_JSON)
// a portfolio consists of an array of arrays, each containing an array of
// stock ticker and associated shares
public Object[][][] getPortfolios(@PathParam("customer-id") int customerId)
{
return clientPortfolios[customerId];
}
@GET
@Path("customer/{customer-id}/portfolio/{portfolio-id}")
@Produces(MediaType.APPLICATION_JSON)
public Object[][] getPortfolio(@PathParam("customer-id") int customerId,
@PathParam("portfolio-id") int portfolioId) {
return getPortfolios(customerId)[portfolioId];
}
@Override
public void afterPropertiesSet() throws Exception {
Object[][][][] clientPortfolios =
{
{
// 3 customers, 3 portfolios each
{new Object[]{"JPM", 10201}, new Object[]{"GE", 20400}, new Object[]{"UTX", 38892}},
{new Object[]{"KO", 12449}, new Object[]{"JPM", 23454}, new Object[]{"MRK", 45344}},
{new Object[]{"WMT", 39583}, new Object[]{"DIS", 95867}, new Object[]{"TRV", 384756}},
}, {
{new Object[]{"GE", 38475}, new Object[]{"MCD", 12395}, new Object[]{"IBM", 91234}},
{new Object[]{"VZ", 22342}, new Object[]{"AXP", 385432}, new Object[]{"UTX", 23432}},
{new Object[]{"IBM", 18343}, new Object[]{"DIS", 45673}, new Object[]{"AAPL", 23456}},
}, {
{new Object[]{"AXP", 34543}, new Object[]{"TRV", 55322}, new Object[]{"NKE", 45642}},
{new Object[]{"CVX", 44332}, new Object[]{"JPM", 12453}, new Object[]{"JNJ", 45433}},
{new Object[]{"MRK", 32346}, new Object[]{"UTX", 46532}, new Object[]{"TRV", 45663}},
}
};
this.clientPortfolios = clientPortfolios;
}
}

@Component×¢½â±íÃ÷ÕâÊÇÒ»¸öSpring×é¼þÀ࣬½«Ëü±©Â¶ÎªÒ»¸ö¶Ëµã¡£ÕýÈçÎÒÃÇ´Ó·½·¨µÄ×¢½âÖп´µ½µÄÄÇÑù£¬@Path×¢½âÉùÃ÷Õâ¸öÀà¿ÉÒÔͨ¹ý¡°portfolios¡±Â·¾¶·ÃÎʵ½£¬Á½¸öÖ§³ÖµÄapiµ÷ÓÿÉÒÔͨ¹ýportfolios/customer/{customer-id}ºÍportfolios/customer/{customer-id}/portfolio/{portfolio-id}¡£ÕâЩ·½·¨Í¨¹ý@GET×¢½â±íÃ÷Ëü·þÎñHTTP GETÇëÇó£¬Õâ¸ö·½·¨ÉùÃ÷·µ»ØÒ»¸öÊý×é²¢×¢½âΪ·µ»ØJson£¬Òò´ËËü»á·µ»ØÒ»¸öJsonÊý×é¡£×¢ÒâÈçºÎÔÚ·½·¨ÉùÃ÷ÖÐʹÓÃ@PathParam×¢½âÀ´´ÓrequestÖÐÌáȡӳÉäµÄ²ÎÊý¡£

£¨±¾ÀýÖУ¬ÎÒÃÇ·µ»ØÓ²±àÂëµÄÖµ¡£µ±È»£¬ÔÚʵ¼ÊÓ¦ÓÃÖУ¬ÊµÏֵķþÎñÔÚÕâÀï»á²éѯÊý¾Ý¿â»òÆäËüһЩ·þÎñ»òÕßÊý¾ÝÔ´¡££©

ÏÖÔÚ¹¹½¨Õâ¸öÏîÄ¿£¬È»ºóÔËÐС£Èç¹ûÄãÊÇÔÚʹÓÃIntelliJ£¬Ëü»á´´½¨Ò»¸öĬÈϵĿÉÔËÐгÌÐò£¬ÄãÖ»Ðèµã»÷ÂÌÉ«µÄ¡°ÔËÐС±¼ýÍ·¡£Ä㻹¿ÉÒÔʹÓÃ

mvn spring-boot:run

»òÕߣ¬Äã¿ÉÒÔÔËÐÐÒ»´Îmaven install£¬È»ºóʹÓÃjava -jar²¢Ö¸¶¨targetĿ¼ÏÂÉú³ÉµÄjarÎļþÀ´ÔËÐÐÕâ¸öÓ¦ÓóÌÐò£º

java -jar target\portfolio-0.0.1-SNAPSHOT.jar

ÎÒÃÇÏÖÔÚÓ¦¸Ã¿ÉÒÔÔÚConsulÖв鿴Õâ¸ö·þÎñ£¬ËùÒÔ·µ»Øä¯ÀÀÆ÷£¬´ò¿ª http://localhost:8500/ui/#/dc1/services£¨Èç¹ûÄãÒѾ­´ò¿ªÁËÕâ¸öµØÖ·£¬Ë¢Ð¾ͿÉÒÔÁË£©¡£

ÎÒÃÇ¿´µ½ÎÒÃǵÄportfolio-serviceÔÚÄÇÀïÁË£¬µ«ÊÇÏÔʾΪfailing£¨Ê§°Ü£©¡£ÄÇÊÇÒòΪConsolÔڵȴý´ÓÎÒÃǵķþÎñ·¢ËÍÒ»¸ö¡°½¡¿µ¡±µÄÐÄÌøÇëÇó¡£

ΪÁËÉú³ÉÐÄÌøÇëÇó£¬ÎÒÃÇÔÚÓ¦ÓóÌÐòµÄpomÎļþÖÐÔö¼ÓSpringBoot ¡°Actuator¡±·þÎñ£¨https://spring.io/guides/gs/actuator-service/£©µÄÒÀÀµ¡£

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

ÔÚpomÎļþÖУ¬Çë×¢Ò⣬Jersey°æ±¾ÔÚconsul-starterºÍjersey-starterÖÐÓÐÒ»¸ö°æ±¾³åÍ»¡£ÎªÁ˽â¾öÕâ¸ö³åÍ»£¬½«jersey starterÒÆÎªµÚÒ»¸öÒÀÀµ¡£

ÄãµÄpomÎļþÏÖÔÚÓ¦¸Ã°üº¬ÈçÏÂÒÀÀµ£º

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

ÖØÆôConsul£¬È»ºóportfolio-service»áÏÔʾÕý³££º

ÏÖÔÚÔÚportfolio-serviceÏÂÓÐÁ½¸öͨ¹ýµÄ½Úµã£¬ÆäÖÐÒ»¸öÊÇÎÒÃÇʵÏÖµÄportfolio·þÎñ£¬ÁíÍâÒ»¸öÊÇÐÄÌø·þÎñ¡£

¼ì²é·ÖÅäµÄ¶Ë¿Ú¡£Äã¿ÉÒÔÔÚÓ¦ÓóÌÐòÊä³ǫ̈¿´µ½£º

INFO 19792 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 57116 (http)

ÄãÒ²¿ÉÒÔÖ±½ÓÔÚconsul UIÖв鿴Õâ¸ö¶Ë¿Ú¡£µã»÷portfolio-service£¬È»ºóÑ¡Ôñ¡°Service 'portfolio-service'¡±Á´½Ó£¬»áÏÔʾ¸Ã·þÎñµÄ¶Ë¿Ú£¬±¾ÀýÖÐΪ57116¡£

µ÷Óà http://localhost:57116/portfolios/customer/1/portfolio/2 £¬È»ºóÄã»á¿´µ½jsonÊý×é [["IBM",18343],["DIS",45673],["AAPL",23456]]¡£

ÎÒÃǵÚÒ»¸ö΢·þÎñ¾ÍÕýʽ¿ª·ÅÁË£¡

¶¨¼Û·þÎñ

½ÓÏÂÀ´£¬ÎÒÃǻᴴ½¨¶¨¼Û·þÎñ£¬ÕâÒ»´ÎʹÓÃSpring RestController¶ø²»ÊÇJersey¡£

¶¨¼Û·þÎñ»á½ÓÊܿͻ§¶ËidºÍportfolio id×÷Ϊ²ÎÊý£¬È»ºó»áʹÓÃÒ»¸öRestTemplate²éѯportfolio·þÎñÀ´»ñÈ¡¹ÉƱ´úÂëºÍ·Ý¶î£¬Ëæºó·µ»Øµ±Ç°µÄ¼Û¸ñ¡££¨ÕâЩ¶¼ÊǼÙÊý¾Ý£¬ËùÒÔ²»ÒªÓÃÕâЩÊý¾ÝÀ´×ö½»Ò×¾ö²ß£¡£©

ʹÓÃÈçÏÂÐÅÏ¢´´½¨Ò»¸öÐÂÏîÄ¿£º

Õâ´ÎÑ¡ÔñWeb¡¢Consul DiscoveryºÍActuatorÒÀÀµ£º

½«ÏîÄ¿ÃüÃûΪ¡°pricing¡±£¬ÔÚÄãÑ¡ÖеÄĿ¼ÖÐÉú³ÉÏîÄ¿¡£

Õâ´ÎÎÒÃÇ»áʹÓÃapplication.properties¶ø²»ÊÇapplication.yml¡£

ÔÚapplication.propertiesÖÐÉèÖÃÃû×ֺͶ˿ÚÈçÏ£º

spring.application.name=pricing
server.port=57216

ÓÃ@EnableDiscoveryClient¸øPricingApplication×¢½â¡£Õâ¸öÀàÓ¦¸Ã¿´ÆðÀ´ÏñÕâÑù£¬¼ÓÉÏpackageºÍimports¡£

@SpringBootApplication
@EnableDiscoveryClient
public class PricingApplication {
public static void main(String[] args) {
SpringApplication.run(PricingApplication.class, args);
}
}

½ÓÏÂÀ´£¬ÎÒÃǻᴴ½¨PricingEndpointÀà¡£Õâ¸öÀàÓÐÒ»µãÈß³¤£¬ÒòΪËüÑÝʾÁËÒ»Ð©ÖØÒªµÄ¹¦ÄÜ£¬°üÀ¨·þÎñ·¢ÏÖ£¨²éÕÒportfolio service£©ºÍʹÓÃRestTemplateÀ´´´½¨Ò»¸ö²éѯ£º

@RestController
@RequestMapping("/pricing")
public class PricingEndpoint implements InitializingBean {
@Autowired
DiscoveryClient client;
Map<String, Double> pricingMap = new HashMap<>();
RestTemplate restTemplate = new RestTemplate();
@GetMapping("/customer/{customer-id}/portfolio/{portfolio-id}")
public List<String> getPricedPortfolio(
@PathVariable("customer-id") Integer customerId,
@PathVariable("portfolio-id") Integer portfolioId)
{
List<ServiceInstance> instances
= client.getInstances("portfolio-service");
ServiceInstance instance
= instances.stream()
.findFirst()
.orElseThrow(() -> new RuntimeException("not found"));
String url = String.format("%s/portfolios/customer/%d/portfolio/%d",
instance.getUri(), customerId, portfolioId);
// query for the portfolios, returned as an array of List
// of size 2, containing a ticker and a position (# of shares)
Object[] portfolio = restTemplate.getForObject(url, Object[].class);
// Look up the share prices, and return a list of Strings, formatted as
// ticker, shares, price, total
List<String> collect = Arrays.stream(portfolio).map(position -> {
String ticker = ((List<String>) position).get(0);
int shares = ((List<Integer>) position).get(1);
double price = getPrice(ticker);
double total = shares * price;
return String.format("%s %d %f %f", ticker, shares, price, total);
}).collect(Collectors.toList());
return collect;
}
private double getPrice(String ticker)
{
return pricingMap.get(ticker);
}
@Override
public void afterPropertiesSet() throws Exception {
pricingMap.put("MMM",201.81);
pricingMap.put("AXP",85.11);
pricingMap.put("AAPL",161.04);
pricingMap.put("BA",236.32);
pricingMap.put("CAT",118.02);
pricingMap.put("CVX",111.31);
pricingMap.put("CSCO",31.7);
pricingMap.put("KO",46.00);
pricingMap.put("DIS",101.92);
pricingMap.put("XOM",78.7);
pricingMap.put("GE",24.9);
pricingMap.put("GS",217.62);
pricingMap.put("HD",155.82);
pricingMap.put("IBM",144.29);
pricingMap.put("INTC",35.66);
pricingMap.put("JNJ",130.8);
pricingMap.put("JPM",89.75);
pricingMap.put("MCD",159.81);
pricingMap.put("MRK",63.89);
pricingMap.put("MSFT",73.65);
pricingMap.put("NKE",52.78);
pricingMap.put("PFE",33.92);
pricingMap.put("PG",92.79);
pricingMap.put("TRV",117.00);
pricingMap.put("UTX",110.12);
pricingMap.put("UNH",198.00);
pricingMap.put("VZ",47.05);
pricingMap.put("V",103.34);
pricingMap.put("WMT", 80.05);
}
}

ΪÁË·¢ÏÖportfolio·þÎñ£¬ÎÒÃÇÐèÒª·ÃÎÊÒ»¸öDiscoveryClient¡£Õâ¿ÉÒÔͨ¹ýSpringµÄ@Autowired×¢½âÇáËÉʵÏÖ

@Autowired
DiscoveryClient client;

È»ºóÔÚ·þÎñµ÷ÓÃÖУ¬ÓÃÕâ¸öDiscoveryClientʵÀýÀ´Ñ°Ö·ÎÒÃǵķþÎñ£º

List<ServiceInstance> instances = client.getInstances("portfolio-service");
ServiceInstance instance = instances.stream().findFirst().orElseThrow(() -> new RuntimeException("not found"));

Ò»µ©Ñ°Ö·µ½Õâ¸ö·þÎñ£¬ÎÒÃÇ¿ÉÒÔÓÃËüÀ´Ö´ÐÐÎÒÃǵÄÇëÇó¡£Õâ¸öÇëÇóÊÇÎÒÃǸù¾ÝÔÚportflo-serviceÖд´½¨µÄapiµ÷ÓÃ×éºÏ¶ø³ÉµÄ¡£

String url = String.format("%s/portfolios/customer/%d/portfolio/%d", instance.getUri(), customerId, portfolioId);

×îÖÕ£¬ÎÒÃÇʹÓÃÒ»¸öRestTemplateÀ´Ö´ÐÐÎÒÃǵÄGETÇëÇó¡£

Object[] portfolio = restTemplate.getForObject(url, Object[].class);

ÐèҪעÒâµÄÊÇ£¬¶ÔÓÚRestControllers£¨ºÍSpringMVC RequestControllerÒ»Ñù£©£¬Â·¾¶±äÁ¿¿ÉÒÔ´Ó@PathVariable×¢½âÖÐÌáÈ¡£¬¶ø²»ÏñJerseyÄÇÑù´Ó@PathParamÖÐÌáÈ¡¡£

ÕâÀïʹÓÃÒ»¸öSpring RestControllerÀ´½«¶¨¼Û·þÎñ·¢²¼³öÈ¥¡£

Îĵµ

ÎÒÃÇÒѾ­¿Ë·þËùÓÐÀ§ÄÑ´´½¨ÁËÎÒÃǵÄ΢·þÎñ£¬µ«ÊÇÈç¹û²»ÈÃÊÀ½çÖªµÀÈçºÎʹÓÃËüÃÇ£¬ËüÃǾͲ»»á²úÉúÈκμÛÖµ¡£

Ϊ´Ë£¬ÎÒÃÇʹÓÃÁËÒ»¸ö³Æ×÷Swagger£¨https://swagger.io/£©µÄ¹¤¾ß¡£SwaggerÊÇÒ»¸ö¼òµ¥Ò×ÓõŤ¾ß£¬²»½öΪÎÒÃǵÄAPIµ÷ÓÃÉú³ÉÎĵµ£¬»¹ÌṩÁËÒ»¸ö¿ÉÒÔÔ®ÒýÕâЩÎĵµµÄÒ×ÓõÄweb¿Í»§¶Ë¡£

Ê×ÏÈ£¬ÈÃÎÒÃÇÔÚpomÎļþÖÐÖ¸¶¨Swagger£º

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>

½ÓÏÂÀ´£¬ÎÒÃÇÐèÒª¸æËßSwaggerÏëҪΪÄÄЩÀàÉú³ÉÎĵµ¡£ÎÒÃÇÐèÒªÒýÈëÒ»¸ö³ÆÎªSwaggerConfigµÄÐÂÀ࣬Ëü°üº¬SwaggerµÄ¸÷ÖÖÅäÖá£

@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("/pricing.*"))
.build();
}
}

ÎÒÃÇ¿ÉÒÔ¿´ÏÂÕâ¸öÀà×öÁËʲô¡£Ê×ÏÈ£¬ÎÒÃÇÓÃ@EnableSwagger2×¢½â±íÃ÷ËüÊÇÒ»¸öSwaggerÅäÖá£

½ÓÏÂÀ´£¬ÎÒÃÇ´´½¨ÁËÒ»¸öDocket bean£¬¸æËßSwaggerÒª±©Â¶ÄÄЩAPI¡£ÔÚÉÏÃæµÄÀý×ÓÖУ¬ÎÒÃǸæËßSwagger±©Â¶ËùÓÐÒÔ¡°/pricing¡±¿ªÍ·µÄ·¾¶¡£»¹¿ÉÒÔÑ¡ÔñÖ¸¶¨classÎļþ¶ø²»ÊÇ·¾¶À´Éú³ÉÎĵµ£º

.apis(RequestHandlerSelectors.basePackage("com.restms.demo")) .paths(PathSelectors.any())

ÖØÆô¶¨¼Û΢·þÎñ£¬È»ºóÔÚä¯ÀÀÆ÷Éϵ÷ÓÃhttp://localhost:57216/swagger-ui.html¡£

µã»÷¡°List Operations¡±°´Å¥À´²é¿´ÏêϸµÄ·þÎñ²Ù×÷¡£

µã»÷¡°Expand Opeartions¡±À´´´½¨Ò»¸ö»ùÓÚformµÄ²éѯµ÷Óá£ÌṩһЩ²ÎÊý£¬µã»÷¡°Try it out!¡±£¬È»ºóµÈ´ýÏìÓ¦½á¹û£º

Äã¿ÉÒÔͨ¹ý¸ø·½·¨Ôö¼ÓSwagger×¢½âÀ´Ôö¼Ó¸ü¶àµÄÑÕÉ«¡£

ÀýÈ磬ʹÓÃ@ApiOperation×¢½âÀ´×°ÊÎÒÑÓеķ½·¨PricingImpl.getPricedPortfolio£º

@ApiOperation(value = "Retrieves a fully priced portfolio",
notes = "Retrieves fully priced portfolio given customer id and portfolio id")
@GetMapping("/customer/{customer-id}/portfolio/{portfolio-id}")
public List<String> getPricedPortfolio(@PathVariable("customer-id") Integer customerId, @PathVariable("portfolio-id") Integer portfolioId)

ÖØÆô²¢Ë¢ÐÂswagger-ui£¬²é¿´Ð´´½¨µÄÎĵµ£º

Ä㻹¿ÉÒÔÓÃSwagger×öÐí¶àÊÂÇ飬¸ü¶àÏêÇéÇë²é¿´ËüµÄÎĵµ¡£

   
6130 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

ÆóÒµ¼Ü¹¹¡¢TOGAFÓëArchiMate¸ÅÀÀ
¼Ü¹¹Ê¦Ö®Â·-ÈçºÎ×öºÃÒµÎñ½¨Ä££¿
´óÐÍÍøÕ¾µçÉÌÍøÕ¾¼Ü¹¹°¸ÀýºÍ¼¼Êõ¼Ü¹¹µÄʾÀý
ÍêÕûµÄArchimateÊÓµãÖ¸ÄÏ£¨°üÀ¨Ê¾Àý£©
Ïà¹ØÎĵµ

Êý¾ÝÖÐ̨¼¼Êõ¼Ü¹¹·½·¨ÂÛÓëʵ¼ù
ÊÊÓÃArchiMate¡¢EA ºÍ iSpace½øÐÐÆóÒµ¼Ü¹¹½¨Ä£
ZachmanÆóÒµ¼Ü¹¹¿ò¼Ü¼ò½é
ÆóÒµ¼Ü¹¹ÈÃSOAÂ䵨
Ïà¹Ø¿Î³Ì

ÔÆÆ½Ì¨Óë΢·þÎñ¼Ü¹¹Éè¼Æ
ÖÐ̨սÂÔ¡¢ÖÐ̨½¨ÉèÓëÊý×ÖÉÌÒµ
ÒÚ¼¶Óû§¸ß²¢·¢¡¢¸ß¿ÉÓÃϵͳ¼Ü¹¹
¸ß¿ÉÓ÷ֲ¼Ê½¼Ü¹¹Éè¼ÆÓëʵ¼ù