{"id":56456,"date":"2018-04-02T11:00:35","date_gmt":"2018-04-02T08:00:35","guid":{"rendered":"http:\/\/examples.javacodegeeks.com\/?p=56456"},"modified":"2021-04-29T13:37:08","modified_gmt":"2021-04-29T10:37:08","slug":"spring-groovy-tutorial","status":"publish","type":"post","link":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/","title":{"rendered":"Spring Framework Groovy Tutorial"},"content":{"rendered":"<p>In this article, we will explain Spring Framework using Groovy. Spring is a Java application framework that provides many useful services for building applications. It has supported Apache Groovy fully since version 4. In this tutorial, we will build a Spring boot application in Groovy.<\/p>\n<div class=\"toc\">\n<h3>Table Of Contents<\/h3>\n<dl>\n<dt><a href=\"#heading1\">1. Introduction<\/a><\/dt>\n<dt><a href=\"#heading2\">2. Technologies Used<\/a><\/dt>\n<dt><a href=\"#heading3\">3. Spring-boot Application<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#heading31\">3.1. Groovy Dependency<\/a><\/dt>\n<dt><a href=\"#heading32\">3.2 Groovy Folders<\/a><\/dt>\n<dt><a href=\"#heading33\">3.3 Groovy Spring Application<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#heading4\">4. Java and Groovy<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#heading41\">4.1 Payroll Interface<\/a><\/dt>\n<dt><a href=\"#heading42\">4.2 Java Classes<\/a><\/dt>\n<dt><a href=\"#heading43\">4.3 Groovy Classes<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#heading5\">5. Demo Java vs Groovy<\/a><\/dt>\n<dt><a href=\"#heading6\">6. Spring and Groovy<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#heading61\">6.1 Spring Properties<\/a><\/dt>\n<dt><a href=\"#heading62\">6.2 POGOs<\/a><\/dt>\n<dt><a href=\"#heading63\">6.3 Address Service<\/a><\/dt>\n<dt><a href=\"#heading64\">6.4 Groovy Spring Application<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#heading7\">7. Demo Spring Groovy Application<\/a><\/dt>\n<dt><a href=\"#heading8\">8. Spring Groovy &#8211; Summary<\/a><\/dt>\n<dt><a href=\"#heading9\">9. Reference<\/a><\/dt>\n<dt><a href=\"#heading10\">10. Download the Source Code<\/a><\/dt>\n<\/dl>\n<\/div>\n<h2 class=\"wp-block-heading\" id=\"h-1-introduction\"><a name=\"heading1\"><\/a>1. Introduction<\/h2>\n<p><a href=\"http:\/\/groovy-lang.org\/\" target=\"_blank\" rel=\"noopener\">Apache&nbsp;Groovy<\/a>&nbsp;(Groovy) is an object-oriented dynamic&nbsp;programming language for the Java platform. It is dynamically compiled to the Java Virtual Machine (JVM) bytecode, and inter-operates with other Java source codes and libraries. Groovy is written in Java. The first version 1.0&nbsp;was released in 2007 to help developers to write a simple, elegant source code instead of the complicated Java code.<\/p>\n<p><a href=\"https:\/\/projects.spring.io\/spring-framework\/\" target=\"_blank\" rel=\"noopener\">Spring Framework<\/a>&nbsp;(Spring) is a Java application framework that provides many useful services for building applications. Spring 1.0 was released in 2004.&nbsp;Spring has supported Groovy fully since version 4 in 2013.<\/p>\n<p><a href=\"https:\/\/projects.spring.io\/spring-boot\/\" target=\"_blank\" rel=\"noopener\">Spring boot<\/a>&nbsp;defines a list of starter projects which each project includes&nbsp;a set of default component dependencies and automatic configuration of components.<\/p>\n<p>In this example, I will create a Spring boot application which utilizes Spring&#8217;s features in Groovy.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-2-technologies-used\"><a name=\"heading2\"><\/a>2. Technologies Used<\/h2>\n<p>The example code in this article was built and run using:<\/p>\n<ul class=\"wp-block-list\">\n<li>Java 1.8.101 (1.8.x will do fine)<\/li>\n<li>Maven 3.3.9 (3.3.x will do fine)<\/li>\n<li>Eclipse Mars (Any Java IDE would work)<\/li>\n<li>Spring boot 1.5.10.RELEASE<\/li>\n<li>Groovy 2.4<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\" id=\"h-3-spring-boot-application\"><a name=\"heading3\"><\/a>3. Spring-boot Application<\/h2>\n<p>The easiest way to generate a Spring-boot application is via the <a href=\"https:\/\/start.spring.io\/\" target=\"_blank\" rel=\"noopener\">Spring starter tool<\/a>. Please check my other article <a href=\"https:\/\/examples.javacodegeeks.com\/enterprise-java\/spring\/data\/spring-data-jparepository-example\/\" target=\"_blank\" rel=\"noopener\">here<\/a> for more details. A maven project will be generated and downloaded to your workstation. Import it into your Eclipse work space. You should have no errors on building it and running it as a Spring Boot Application.<\/p>\n<p>We will change it to a Groovy spring application with three steps:<\/p>\n<ol class=\"wp-block-list\">\n<li>Add a Groovy dependency in the <code>pom.xml<\/code><\/li>\n<li>Add a Groovy source folder<\/li>\n<li>Change Spring Application to a Groovy class<\/li>\n<\/ol>\n<h3 class=\"wp-block-heading\" id=\"h-3-1-groovy-dependency\"><a name=\"heading31\"><\/a>3.1 Groovy Dependency<\/h3>\n<p>The generated <code>pom.xml<\/code>&nbsp;does not include the Groovy library. We will add it as a dependency.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>pom.xml<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\n\txsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\n\t&lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\n\n\t&lt;groupId&gt;jcg.zheng.demo&lt;\/groupId&gt;\n\t&lt;artifactId&gt;groovy-spring&lt;\/artifactId&gt;\n\t&lt;version&gt;0.0.1-SNAPSHOT&lt;\/version&gt;\n\t&lt;packaging&gt;jar&lt;\/packaging&gt;\n\n\t&lt;name&gt;groovy-spring&lt;\/name&gt;\n\t&lt;description&gt;Demo project for Spring Boot&lt;\/description&gt;\n\n\t&lt;parent&gt;\n\t\t&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n\t\t&lt;artifactId&gt;spring-boot-starter-parent&lt;\/artifactId&gt;\n\t\t&lt;version&gt;1.5.10.RELEASE&lt;\/version&gt;\n\t\t&lt;relativePath\/&gt; &lt;!-- lookup parent from repository --&gt;\n\t&lt;\/parent&gt;\n\n\t&lt;properties&gt;\n\t\t&lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt;\n\t\t&lt;project.reporting.outputEncoding&gt;UTF-8&lt;\/project.reporting.outputEncoding&gt;\n\t\t&lt;java.version&gt;1.8&lt;\/java.version&gt;\n\t&lt;\/properties&gt;\n\n\t&lt;dependencies&gt;\n\t\t&lt;dependency&gt;\n\t\t\t&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n\t\t\t&lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\n\t\t&lt;\/dependency&gt;\n\n\t\t&lt;dependency&gt;\n\t\t\t&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n\t\t\t&lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;\n\t\t\t&lt;scope&gt;test&lt;\/scope&gt;\n\t\t&lt;\/dependency&gt;\n\t\t&lt;dependency&gt;\n\t\t\t&lt;groupId&gt;org.codehaus.groovy&lt;\/groupId&gt;\n\t\t\t&lt;artifactId&gt;groovy-all&lt;\/artifactId&gt;\n\t\t&lt;\/dependency&gt;\n\t&lt;\/dependencies&gt;\n\n\t&lt;build&gt;\n\t\t&lt;plugins&gt;\n\t\t\t&lt;plugin&gt;\n\t\t\t\t&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n\t\t\t\t&lt;artifactId&gt;spring-boot-maven-plugin&lt;\/artifactId&gt;\n\t\t\t&lt;\/plugin&gt;\n\t\t&lt;\/plugins&gt;\n\t&lt;\/build&gt;\n\n&lt;\/project&gt;\n<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-3-2-groovy-folders\"><a name=\"heading32\"><\/a>3.2 Groovy Folders<\/h3>\n<p>The generated project has a <code>Java<\/code> source folder. We will add two&nbsp;folders:&nbsp;<code>src\/main\/groovy<\/code> and <code>src\/test\/groovy<\/code>. Then we will include them as the build resources.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2018\/03\/groovy-spring.jpg\"><img decoding=\"async\" width=\"402\" height=\"454\" src=\"http:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2018\/03\/groovy-spring.jpg\" alt=\"spring framework groovy - Project Structure\" class=\"wp-image-56548\" srcset=\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2018\/03\/groovy-spring.jpg 402w, https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2018\/03\/groovy-spring-266x300.jpg 266w\" sizes=\"(max-width: 402px) 100vw, 402px\" \/><\/a><figcaption>Figure 1 Project Structure<\/figcaption><\/figure>\n<\/div>\n<h3 class=\"wp-block-heading\" id=\"h-3-3-spring-framework-application-in-groovy\"><a name=\"heading33\"><\/a>3.3 Spring Framework Application in Groovy<\/h3>\n<p>The generated <code>GroovySpringApplication<\/code> is a <code>Java<\/code> class. We will change it to a&nbsp;<code>Groovy<\/code> class and move it under the&nbsp;<code>src\/main\/groovy<\/code> folder.<\/p>\n<p>You can execute <code>mvn install<\/code> to build it and then run it as a Spring boot application.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-4-java-and-groovy\"><a name=\"heading4\"><\/a>4. Java and Groovy<\/h2>\n<p>We will define <code>Payroll<\/code>&nbsp;interface and implement it with both <code>Java<\/code> and <code>Groovy<\/code> and compare their performance.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-4-1-payroll-interface\"><a name=\"heading41\"><\/a>4.1 Payroll Interface<\/h3>\n<p>Define <code>Payroll<\/code> interface to calculate the department&#8217;s budget based on the time period.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Payroll.java<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java;wrap-lines:false\">package jcg.zheng.demo.groovyspring.service;\n\nimport java.math.BigDecimal;\n\nimport jcg.zheng.demo.groovyspring.model.BudgetType;\nimport jcg.zheng.demo.groovyspring.model.GDepartment;\nimport jcg.zheng.demo.groovyspring.model.JDepartment;\n\npublic interface Payroll {\n\n\tBigDecimal caculateBudget(JDepartment department, BudgetType type);\n\tBigDecimal caculateBudget(GDepartment department, BudgetType type);\n\n}\n<\/pre>\n<p><strong>Note<\/strong>:&nbsp; It defines <code>caculateBudget<\/code> method for both Java Department and Groovy Department. We use it to demonstrate the method&#8217;s performance.<\/p>\n<p>Define <code>BudgetType<\/code> <code>enum<\/code> for four time periods.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>BudgetType.java<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.model;\n\nimport java.math.BigDecimal;\n\npublic enum BudgetType {\n\n\tYEARLY, QUARTERLY, MONTHLY, WEEKLY;\n\n\tpublic BigDecimal workingHours() {\n\t\tBigDecimal workingHours = new BigDecimal(0);\n\t\tswitch (this) {\n\t\tcase YEARLY:\n\t\t\tworkingHours = new BigDecimal(2080);\n\t\tcase QUARTERLY:\n\t\t\tworkingHours = new BigDecimal(520);\n\t\tcase MONTHLY:\n\t\t\tworkingHours = new BigDecimal(173.34);\n\t\tcase WEEKLY:\n\t\t\tworkingHours = new BigDecimal(40);\n\t\t}\n\t\treturn workingHours;\n\t}\n\n}\n<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-4-2-java-classes\"><a name=\"heading42\"><\/a>4.2 Java Classes<\/h3>\n<p>In this step, we will create three Java classes to implement the <code>Payroll<\/code> interface.<\/p>\n<p>Define a department class which contains a list of employees.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>JDepartment.java<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.model;\n\nimport java.util.List;\n\npublic class JDepartment {\n\tprivate int id;\n\n\tprivate List employees;\n\n\tpublic List getEmployees() {\n\t\treturn employees;\n\t}\n\n\tpublic void setEmployees(List employees) {\n\t\tthis.employees = employees;\n\t}\n\n\tpublic int getId() {\n\t\treturn id;\n\t}\n\n\tpublic void setId(int id) {\n\t\tthis.id = id;\n\t}\n}\n<\/pre>\n<p>Define an employee class which contains the employee&#8217;s first name, last name, and hourly pay rate.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>JEmployee.java<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.model;\n\nimport java.math.BigDecimal;\n\npublic class JEmployee {\n\tpublic JEmployee() {\n\t\tsuper();\n\t}\n\n\tprivate String firstName;\n\tprivate String lastName;\n\tprivate int id;\n\tprivate BigDecimal hourlyRate;\n\n\tpublic BigDecimal caculatePay(BigDecimal hours) {\n\t\treturn hourlyRate.multiply(hours);\n\t}\n\n\tpublic String getFirstName() {\n\t\treturn firstName;\n\t}\n\n\tpublic void setFirstName(String firstName) {\n\t\tthis.firstName = firstName;\n\t}\n\n\tpublic String getLastName() {\n\t\treturn lastName;\n\t}\n\n\tpublic void setLastName(String lastName) {\n\t\tthis.lastName = lastName;\n\t}\n\n\tpublic int getId() {\n\t\treturn id;\n\t}\n\n\tpublic void setId(int id) {\n\t\tthis.id = id;\n\t}\n\n\tpublic BigDecimal getHourlyRate() {\n\t\treturn hourlyRate;\n\t}\n\n\tpublic void setHourlyRate(BigDecimal hourlyRate) {\n\t\tthis.hourlyRate = hourlyRate;\n\t}\n\n}\n<\/pre>\n<p>Implement the <code>Payroll<\/code> interface&#8217;s two methods to calculate a given department&#8217;s budget.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>JPayrollImpl.java<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java;wrap-lines:false\">package jcg.zheng.demo.groovyspring.service.impl;\n\nimport java.math.BigDecimal;\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.springframework.stereotype.Component;\n\nimport jcg.zheng.demo.groovyspring.model.BudgetType;\nimport jcg.zheng.demo.groovyspring.model.GDepartment;\nimport jcg.zheng.demo.groovyspring.model.JDepartment;\nimport jcg.zheng.demo.groovyspring.service.Payroll;\n\n@Component(\"javaPayroll\")\npublic class JPayrollImp implements Payroll {\n\n\t@Override\n\tpublic BigDecimal caculateBudget(JDepartment department, BudgetType type) {\n\t\tInstant start = Instant.now();\n\n\t\tList values = new ArrayList();\n\t\tdepartment.getEmployees().forEach(emp -&gt; values.add(emp.caculatePay(type.workingHours())));\n\n\t\tBigDecimal result = values.stream().reduce(BigDecimal::add).get();\n\n\t\tInstant end = Instant.now();\n\n\t\tSystem.out.println(\"Java caculateBudget for JDepartment took \" + Duration.between(start, end));\n\n\t\treturn result;\n\t}\n\n\t@Override\n\tpublic BigDecimal caculateBudget(GDepartment department, BudgetType type) {\n\t\tInstant start = Instant.now();\n\n\t\tList values = new ArrayList();\n\t\tdepartment.getEmployees().forEach(emp -&gt; values.add(emp.caculatePay(type.workingHours())));\n\n\t\tBigDecimal result = values.stream().reduce(BigDecimal::add).get();\n\n\t\tInstant end = Instant.now();\n\n\t\tSystem.out.println(\"Java caculateBudget for GDepartment took \" + Duration.between(start, end));\n\n\t\treturn result;\n\t}\n\n}\n<\/pre>\n<p>Create a Junit test class for&nbsp;<code>JPayrollImp<\/code>.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p><span style=\"text-decoration: underline;\"><em>JPayrollImpTest.java<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.service.impl;\n\nimport static org.junit.Assert.*;\n\nimport java.math.BigDecimal;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit4.SpringRunner;\n\nimport jcg.zheng.demo.groovyspring.model.BudgetType;\nimport jcg.zheng.demo.groovyspring.model.GDepartment;\nimport jcg.zheng.demo.groovyspring.model.GEmployee;\nimport jcg.zheng.demo.groovyspring.model.JDepartment;\nimport jcg.zheng.demo.groovyspring.model.JEmployee;\nimport jcg.zheng.demo.groovyspring.service.Payroll;\n\n@RunWith(SpringRunner.class)\n@SpringBootTest\npublic class JPayrollImpTest {\n\n\t@Autowired\n\t@Qualifier(\"javaPayroll\")\n\tprivate Payroll javaPayroll;\n\n\t@Test\n\tpublic void test_JavaPayroll_caculateBudget_for_JDepartment_yearly() {\n\t\tJDepartment dept = new JDepartment();\n\n\t\tList reports = new ArrayList();\n\t\treports.add(buildJEmployee(\"Mary\", \"Zheng\", new BigDecimal(20)));\n\t\treports.add(buildJEmployee(\"Alex\", \"Zheng\", new BigDecimal(10)));\n\t\treports.add(buildJEmployee(\"Allen\", \"Zheng\", new BigDecimal(8)));\n\n\t\tdept.setEmployees(reports);\n\n\t\tBigDecimal budget = javaPayroll.caculateBudget(dept, BudgetType.YEARLY);\n\t\tassertTrue(budget.compareTo(new BigDecimal(1520)) == 0);\n\t}\n\n\t@Test\n\tpublic void test_JavaPayroll_caculateBudget_for_GDepartment_yearly() {\n\t\tGDepartment dept = new GDepartment();\n\n\t\tList reports = new ArrayList();\n\t\treports.add(buildGEmployee(\"Mary\", \"Zheng\", new BigDecimal(20)));\n\t\treports.add(buildGEmployee(\"Alex\", \"Zheng\", new BigDecimal(10)));\n\t\treports.add(buildGEmployee(\"Allen\", \"Zheng\", new BigDecimal(8)));\n\n\t\tdept.setEmployees(reports);\n\n\t\tBigDecimal budget = javaPayroll.caculateBudget(dept, BudgetType.YEARLY);\n\t\tassertTrue(budget.compareTo(new BigDecimal(1520)) == 0);\n\t}\n\n\tprivate JEmployee buildJEmployee(String fname, String lname, BigDecimal money) {\n\t\tJEmployee mary = new JEmployee();\n\t\tmary.setFirstName(fname);\n\t\tmary.setLastName(lname);\n\t\tmary.setHourlyRate(money);\n\t\treturn mary;\n\t}\n\n\tprivate GEmployee buildGEmployee(String fname, String lname, BigDecimal money) {\n\t\tGEmployee mary = new GEmployee();\n\t\tmary.setFirstName(fname);\n\t\tmary.setLastName(lname);\n\t\tmary.setHourlyRate(money);\n\t\treturn mary;\n\t}\n\n}\n<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-4-3-groovy-classes\"><a name=\"heading43\"><\/a>4.3 Groovy Classes<\/h3>\n<p>Groovy was introduced to ease the Java syntax&#8217;s complexity.&nbsp;The&nbsp;<code><a href=\"http:\/\/docs.groovy-lang.org\/docs\/groovy-2.4.6\/html\/gapi\/groovy\/transform\/Canonical.html\" target=\"_blank\" rel=\"noopener\">@Canonical<\/a><\/code> annotation assists Groovy developers to write shorter code.&nbsp;In this step, we will create three Groovy classes to implement the <code>Payroll<\/code> interface.<\/p>\n<p>Define a department class which contains a list of employees. It&#8217;s much shorter and cleaner comparing to the Java class created in <a href=\"#heading42\">step 4.2<\/a>.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>GDepartment.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.model\n\nimport groovy.transform.*\n\n@Canonical\nclass GDepartment {\n\tint id\t\n\tList employees\n\n}\n<\/pre>\n<p>Define an employee class which contains the employee&#8217;s first name, last name, and hourly pay rate.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>GEmployee.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.model\n\nimport groovy.transform.*\n\n@Canonical\nclass GEmployee {\n\tString firstName\n\tString lastName\n\tint id\n\tBigDecimal hourlyRate\n\t\n\tpublic BigDecimal caculatePay(BigDecimal hours) {\n\t\thourlyRate.multiply(hours)\n\t}\n}\n<\/pre>\n<p>Implement the <code>Payroll<\/code> interface&#8217;s two methods to calculate a given department&#8217;s budget.<\/p>\n<p>We can use Spring <code>@Component<\/code> annotation to name it <code>groovyPayroll<\/code> as a Spring bean. We also add time tracking to calculate the performance time.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>GPayrollImpl.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.component\n\nimport java.time.Duration\nimport java.util.ArrayList\nimport java.util.List\n\nimport org.springframework.stereotype.Component\n\nimport groovy.time.TimeCategory\nimport groovy.time.TimeDuration\nimport jcg.zheng.demo.groovyspring.model.BudgetType\nimport jcg.zheng.demo.groovyspring.model.GDepartment\nimport jcg.zheng.demo.groovyspring.model.JDepartment\nimport jcg.zheng.demo.groovyspring.service.Payroll\n\n@Component(\"groovyPayroll\")\nclass GPayrollImpl implements Payroll{\n\n\t@Override\n\tpublic BigDecimal caculateBudget(JDepartment department, BudgetType type) {\n\t\tdef timeStart = new Date()\n\t\tList values = new ArrayList()\n\n\t\tdepartment.getEmployees().each { \n\t\t\tvalues.add(it.caculatePay(type.workingHours()))}\n\n\t\tdef timeStop = new Date()\n\t\tTimeDuration duration = TimeCategory.minus(timeStop, timeStart)\n\t\tprintln \"Groovy caculateBudget for JDepartment took \" + duration\n\n\t\tvalues.sum();\n\t}\n\n\t@Override\n\tpublic BigDecimal caculateBudget(GDepartment department, BudgetType type) {\n\t\tdef timeStart = new Date()\n\t\tList values = new ArrayList()\n\n\t\tdepartment.getEmployees().each {\n\t\t\tvalues.add(it.caculatePay(type.workingHours()))}\n\n\t\tdef timeStop = new Date()\n\t\tTimeDuration duration = TimeCategory.minus(timeStop, timeStart)\n\t\tprintln \"Groovy caculateBudget for GDepartment took \" + duration\n\t\tvalues.sum();\n\t}\n}\n<\/pre>\n<p>Create a Junit test class for&nbsp;<code>GPayrollImp<\/code>.&nbsp;We use Spring <code>@Autowired<\/code> annotation along with <code>@Qualifier<\/code> to find the Groovy <code>Payroll<\/code> bean.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>GPayrollImpTest.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java;wrap-lines:false\">package jcg.zheng.demo.groovyspring.component\n\nimport static org.junit.Assert.assertTrue\n\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.springframework.beans.factory.annotation.Autowired\nimport org.springframework.beans.factory.annotation.Qualifier\nimport org.springframework.boot.test.context.SpringBootTest\nimport org.springframework.test.context.junit4.SpringRunner\n\nimport jcg.zheng.demo.groovyspring.model.BudgetType\nimport jcg.zheng.demo.groovyspring.model.GDepartment\nimport jcg.zheng.demo.groovyspring.model.GEmployee\nimport jcg.zheng.demo.groovyspring.model.JDepartment\nimport jcg.zheng.demo.groovyspring.model.JEmployee\nimport jcg.zheng.demo.groovyspring.service.Payroll\n\n@RunWith(SpringRunner.class)\n@SpringBootTest\nclass GroovyPayrollTest {\n\n\t@Autowired\n\t@Qualifier(\"groovyPayroll\")\n\tprivate Payroll groovyPayroll\n\n\t@Test\n\tpublic void test_GroovyPayroll_caculateBudget_for_GDepartment_yearly() {\n\t\tGDepartment department = new GDepartment()\n\n\t\tList reports = [\n\t\t\tnew GEmployee(firstName:\"Mary\", lastName:\"Zheng\", hourlyRate:new BigDecimal(20)),\n\t\t\tnew GEmployee(firstName:\"Alex\", lastName:\"Zheng\", hourlyRate:new BigDecimal(10)),\n\t\t\tnew GEmployee(firstName:\"Allen\", lastName:\"Zheng\", hourlyRate:new BigDecimal(8))\n\t\t]\n\n\t\tdepartment.setEmployees(reports);\n\n\t\tdef ret = groovyPayroll.caculateBudget(department, BudgetType.YEARLY)\n\t\tassertTrue(ret.compareTo(new BigDecimal(1520)) == 0);\n\t}\n\n\t@Test\n\tpublic void test_GroovyPayroll_caculateBudget_for_JDepartment_yearly() {\n\t\tJDepartment department = new JDepartment()\n\n\t\tList reports = [\n\t\t\tnew JEmployee(firstName:\"Mary\", lastName:\"Zheng\", hourlyRate:new BigDecimal(20)),\n\t\t\tnew JEmployee(firstName:\"Alex\", lastName:\"Zheng\", hourlyRate:new BigDecimal(10)),\n\t\t\tnew JEmployee(firstName:\"Allen\", lastName:\"Zheng\", hourlyRate:new BigDecimal(8))\n\t\t]\n\n\t\tdepartment.setEmployees(reports);\n\n\t\tdef ret = groovyPayroll.caculateBudget(department, BudgetType.YEARLY)\n\t\tassertTrue(ret.compareTo(new BigDecimal(1520)) == 0);\n\t}\n}\n<\/pre>\n<h2 class=\"wp-block-heading\" id=\"h-5-demo-java-vs-groovy\"><a name=\"heading5\"><\/a>5. Demo Java vs Groovy<\/h2>\n<p>Execute <code>mvn install<\/code> to build and run <code>JPayrollImpTest<\/code> and <code>GPayrollImpTest<\/code> and see the output below.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>JPayrollImpTest output<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:bash;wrap-lines:false; highlight:[3]\">2018-03-28 21:16:58.299  INFO 10460 --- [           main] j.z.d.g.service.impl.JPayrollImpTest     : Started JPayrollImpTest in 8.053 seconds (JVM running for 9.671)\nJava caculateBudget for GDepartment took PT0.039S\nJava caculateBudget for JDepartment took PT0.003S\n<\/pre>\n<p><span style=\"text-decoration: underline;\"><em>GPayrollImpTest output<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:bash;wrap-lines:false\">2018-03-28 21:18:37.369  INFO 7588 --- [           main] j.z.d.g.component.GroovyPayrollTest      : Started GroovyPayrollTest in 5.96 seconds (JVM running for 7.935)\nGroovy caculateBudget for GDepartment took 0.036 seconds\nGroovy caculateBudget for JDepartment took 0.007 seconds\n<\/pre>\n<p>Testing output shows that the Java implementation of the payroll service with the Java POJO class is the fastest of all four tests.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-6-spring-framework-and-groovy\"><a name=\"heading6\"><\/a>6. Spring Framework and Groovy<\/h2>\n<p>In this step, I will demonstrate how to invoke a Rest service and parse the results in Groovy.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-6-1-spring-properties\"><a name=\"heading61\"><\/a>6.1 Spring Properties<\/h3>\n<p>The Rest service is a public service which gets all the country&#8217;s information and gets state&#8217;s information for given country.<\/p>\n<p>Add the service host name and logging level in the Spring properties file.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>application.properties<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:bash\">AddressService.HostUrl=http:\/\/services.groupkt.com\n\nlogging.level.org.springframework=INFO\nlogging.level.jcg.zheng.demo=DEBUG<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-6-2-pogos\"><a name=\"heading62\"><\/a>6.2 POGOs<\/h3>\n<p>Open browser and go to&nbsp;<a href=\"http:\/\/services.groupkt.com\/country\/get\/all\" target=\"_blank\" rel=\"noopener\">http:\/\/services.groupkt.com\/country\/get\/all<\/a> get all the country&#8217;s information.&nbsp; Go to&nbsp;<a href=\"http:\/\/services.groupkt.com\/state\/get\/USA\/all\" target=\"_blank\" rel=\"noopener\">http:\/\/services.groupkt.com\/state\/get\/USA\/all<\/a> to get all the state&#8217;s information for USA. Both services return a <code>Json<\/code> object which contains a <code>List<\/code> of <code>String<\/code> messages and List of countries or states.<\/p>\n<p>We will create four POGOs to match the Rest service results. Then use <code>JsonSlurper<\/code> to parse the results to the expected data type.<\/p>\n<p><code>GCountry<\/code> class contains <code>name<\/code>,&nbsp;<code>alpha2_code<\/code>, and <code>alpha3_code<\/code>.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>GCountry.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.model;\n\nimport groovy.transform.*\n\n@Canonical\nclass GCountry {\n\n\tString name\n\tString alpha2_code\n\tString alpha3_code\n}\n<\/pre>\n<p><code>GState<\/code> class contains <code>name<\/code>,&nbsp;<code>abbr<\/code>, and <code>capital<\/code>, etc.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>GState.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.model;\n\nimport groovy.transform.*\n\n@Canonical\nclass GState {\n\tLong id\n\tString country\n\tString name\n\tString abbr\n\tString area\n\tString capital\n\tString largest_city\n}\n<\/pre>\n<p><code>GResponse<\/code> class contains <code>messages<\/code> and <code>result<\/code>.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>GResponse.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.model;\nimport groovy.transform.*\n\n@Canonical\nclass GResponse {\n\tList&lt;String&gt; messages\n\n\tList&lt;Object&gt; result\n}\n<\/pre>\n<p><code>GResponseWrapper<\/code> class contains <code>RestResponse<\/code>.[ulp id=&#8217;7POIYxRf1FUtPpmL&#8217; name=&#8217;Spring Framework Cookbook Inline&#8217;]<\/p>\n<p><span style=\"text-decoration: underline;\"><em>GResponseWrapper.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java\">package jcg.zheng.demo.groovyspring.model;\n\nimport groovy.json.internal.LazyMap\nimport groovy.transform.*\n@Canonical\nclass GResponseWrapper {\n\tGResponse RestResponse\n}\n<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-6-3-address-service\"><a name=\"heading63\"><\/a>6.3 Address Service<\/h3>\n<p>Create an address service and annotate it with <code>@Component<\/code>. It invokes a REST API service to get all the country&#8217;s information. The results is cached into the memory with the&nbsp;<code><a href=\"http:\/\/docs.groovy-lang.org\/next\/html\/gapi\/groovy\/transform\/Memoized.html\" target=\"_blank\" rel=\"noopener\">@Memoized<\/a><\/code> annotation.<\/p>\n<p><code>AddressService<\/code> class contains two methods: <code>getCountries<\/code> and <code>getStates<\/code>.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>AddressService.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java;wrap-lines:false\">package jcg.zheng.demo.groovyspring.component\n\nimport org.slf4j.Logger\nimport org.slf4j.LoggerFactory\nimport org.springframework.beans.factory.annotation.Value\nimport org.springframework.cache.annotation.Cacheable\nimport org.springframework.stereotype.Component\n\nimport groovy.json.JsonSlurper\nimport groovy.transform.Memoized\nimport jcg.zheng.demo.groovyspring.model.GCountry\nimport jcg.zheng.demo.groovyspring.model.GResponseWrapper\nimport jcg.zheng.demo.groovyspring.model.GState\n\n@Component\nclass AddressService {\n\t@Value('${AddressService.HostUrl}')\n\tprivate String serviceHostUrl\n\n\tprivate String countryPath = \"\/country\/get\/all\"\n\n\tprivate String statePath = \"\/state\/get\/\"\n\n\n\tprivate static final Logger logger = LoggerFactory.getLogger(AddressService.class)\n\n\t@Memoized\n\tList&lt;GState&gt; getStates(String countryCode){\n\t\tList&lt;GState&gt; states = new ArrayList&lt;&gt;()\n\t\tString getResult = new URL(serviceHostUrl + statePath + countryCode + \"\/all\").text\n\t\tlogger.debug( \"getStates called rest service.\")\n\t\tdef jsonMap = new JsonSlurper().parseText(getResult)\n\n\t\tGResponseWrapper rep = new GResponseWrapper(jsonMap)\n\t\treturn rep.getRestResponse().getResult()\n\t}\n\n\t@Memoized\n\tList&lt;GCountry&gt; getCountries(){\n\t\tList&lt;GCountry&gt; countryList = new ArrayList&lt;&gt;()\n\t\tString getResult = new URL(serviceHostUrl + countryPath).text\n\t\tlogger.debug( \"getCountries called rest service.\")\n\t\tdef jsonMap = new JsonSlurper().parseText(getResult)\n\n\t\tGResponseWrapper rep = new GResponseWrapper(jsonMap)\n\t\t\n\t\treturn rep.getRestResponse().getResult()\n\t}\n}\n<\/pre>\n<p>Create <code>AddressServiceTest<\/code> to test both <code>getCountries<\/code> and <code>getStates<\/code>.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>AddressServiceTest.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java;wrap-lines:false\">package jcg.zheng.demo.groovyspring.component\n\nimport static org.junit.Assert.*\n\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.springframework.beans.factory.annotation.Autowired\nimport org.springframework.boot.test.context.SpringBootTest\nimport org.springframework.test.context.junit4.SpringRunner\n\nimport groovy.time.TimeCategory\nimport groovy.time.TimeDuration\n\nimport jcg.zheng.demo.groovyspring.component.AddressService\nimport jcg.zheng.demo.groovyspring.model.*\n\n@RunWith(SpringRunner.class)\n@SpringBootTest\nclass AddressServiceTest {\n\n\t@Autowired\n\tprivate AddressService addressService\n\n\t@Test\n\tpublic void test_get_allcountries() {\n\t\tdef timeStart = new Date()\n\n\t\tList countries = addressService.getCountries();\n\n\t\tdef timeStop = new Date()\n\n\t\tcountries = addressService.getCountries();\n\n\t\tdef timeStop2 = new Date()\n\n\t\tTimeDuration duration = TimeCategory.minus(timeStop, timeStart)\n\t\tTimeDuration duration2 = TimeCategory.minus(timeStop2, timeStop)\n\n\t\tprintln \"Groovy first getCountries took \" + duration\n\t\tprintln \"Groovy second getCountries took \" + duration2\n\n\t\tassertTrue(countries.size() == 249)\n\t}\n\n\t@Test\n\tpublic void test_get_USA_states() {\n\t\tdef timeStart = new Date()\n\n\t\tList usStates = addressService.getStates(\"USA\");\n\n\t\tdef timeStop = new Date()\n\n\t\tusStates = addressService.getStates(\"USA\");\n\n\t\tdef timeStop2 = new Date()\n\n\t\tTimeDuration duration = TimeCategory.minus(timeStop, timeStart)\n\n\t\tTimeDuration duration2 = TimeCategory.minus(timeStop2, timeStop)\n\n\t\tprintln \"Groovy second getStates took \" + duration\n\t\tprintln \"Groovy second getStates took \" + duration2\n\n\t\tassertTrue(usStates.size() == 55)\n\t}\n}\n<\/pre>\n<p>Run the <code>AddressServiceTest<\/code> and confirm data for the countries and states is cached.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>AddressServiceTest output<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:bash;wrap-lines:false\">2018-03-28 22:01:06.764  INFO 5060 --- [           main] j.z.d.g.component.AddressServiceTest     : Started AddressServiceTest in 4.743 seconds (JVM running for 6.208)\n2018-03-28 22:01:07.070 DEBUG 5060 --- [           main] j.z.d.g.component.AddressService         : getCountries called rest service.\nGroovy first getCountries took 0.256 seconds\nGroovy second getCountries took 0\n2018-03-28 22:01:07.210 DEBUG 5060 --- [           main] j.z.d.g.component.AddressService         : getStates called rest service.\nGroovy second getStates took 0.079 seconds\nGroovy second getStates took 0\n<\/pre>\n<h3 class=\"wp-block-heading\" id=\"h-6-4-groovy-spring-application\"><a name=\"heading64\"><\/a>6.4 Groovy Spring Application<\/h3>\n<p><code>GroovySpringApplication<\/code> is a Groovy class which annotates with Spring annotation driven configuration annotation <code>@SpringBootApplication<\/code>. It finds <code>javaPayroll<\/code> and invokes its <code>caculateBudget<\/code> for a given department. It also finds the <code>AddressService<\/code> beans and finds the <code>USA<\/code> from the <code>getCountries<\/code> returned countries and then gets all the USA states from <code>getStates<\/code> service.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>GroovySpringApplication.groovy<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:java;wrap-lines:false\">package jcg.zheng.demo.groovyspring\n\nimport org.springframework.boot.SpringApplication\nimport org.springframework.boot.autoconfigure.SpringBootApplication\nimport org.springframework.context.ConfigurableApplicationContext\n\nimport jcg.zheng.demo.groovyspring.component.AddressService\nimport jcg.zheng.demo.groovyspring.model.BudgetType\nimport jcg.zheng.demo.groovyspring.model.GCountry\nimport jcg.zheng.demo.groovyspring.model.GDepartment\nimport jcg.zheng.demo.groovyspring.model.GEmployee\nimport jcg.zheng.demo.groovyspring.model.GState\nimport jcg.zheng.demo.groovyspring.service.Payroll\n\n@SpringBootApplication\npublic class GroovySpringApplication {\n\n\tpublic static void main(String[] args) {\n\t\tConfigurableApplicationContext context = SpringApplication.run(GroovySpringApplication.class, args)\n\t\t\n\t\tprintYearlyBudget(context)\n\t\n\t\tprintAddress(context)\n\t}\n\n\tprivate static printYearlyBudget(ConfigurableApplicationContext context) {\n\t\tGDepartment department = new GDepartment(id:1)\n\n\t\tList reports = [\n\t\t\tnew GEmployee(firstName:\"Mary\", lastName:\"Zheng\", hourlyRate:new BigDecimal(20)),\n\t\t\tnew GEmployee(firstName:\"Alex\", lastName:\"Zheng\", hourlyRate:new BigDecimal(10)),\n\t\t\tnew GEmployee(firstName:\"Allen\", lastName:\"Zheng\", hourlyRate:new BigDecimal(8))\n\t\t]\n\n\t\tdepartment.setEmployees(reports)\n\t\tPayroll payroll = context.getBean(\"javaPayroll\")\n\t\tprintln \"Departement 1 yearly budget: \" + payroll.caculateBudget(department, BudgetType.YEARLY)\n\t}\n\n\tprivate static printAddress(ConfigurableApplicationContext context) {\n\t\tAddressService addressService = context.getBean(AddressService.class)\n\t\tList countries = addressService.getCountries()\n\t\tdef usa = countries.find{it.get(\"alpha3_code\").equalsIgnoreCase(\"USA\")}\n\t\tprintln \"Found USA \" + usa\n\n\t\tList usStates = addressService.getStates(\"USA\")\n\t\tprintln \"US States :\" + usStates\n\t}\n}\n<\/pre>\n<h2 class=\"wp-block-heading\" id=\"h-7-demo-spring-groovy-application\"><a name=\"heading7\"><\/a>7. Demo Spring Groovy Application<\/h2>\n<p>Execute the Spring boot application.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Application Output<\/em><\/span><\/p>\n<pre class=\"wp-block-preformatted brush:bash;wrap-lines:false\">2018-03-28 21:36:19.045  INFO 9708 --- [           main] j.z.d.g.GroovySpringApplication          : Started GroovySpringApplication in 5.715 seconds (JVM running for 7.525)\nJava caculateBudget for GDepartment took PT0.011S\nDepartement 1 yearly budget: 1520\n2018-03-28 21:36:19.358 DEBUG 9708 --- [           main] j.z.d.g.component.AddressService         : getCountries called rest service.\nFound USA [name:United States of America, alpha2_code:US, alpha3_code:USA]\n2018-03-28 21:36:19.468 DEBUG 9708 --- [           main] j.z.d.g.component.AddressService         : getStates called rest service.\nUS States :[[id:1, country:USA, name:Alabama, abbr:AL, area:135767SKM, largest_city:Birmingham, capital:Montgomery], [id:2, country:USA, name:Alaska, abbr:AK, area:1723337SKM, largest_city:Anchorage, capital:Juneau], [id:3, country:USA, name:Arizona, abbr:AZ, area:113594SKM, largest_city:Phoenix, capital:Phoenix], [id:4, country:USA, name:Arkansas, abbr:AR, area:52035SKM, largest_city:Little Rock, capital:Little Rock], [id:5, country:USA, name:California, abbr:CA, area:423967SKM, largest_city:Los Angeles, capital:Sacramento], [id:6, country:USA, name:Colorado, abbr:CO, area:103642SKM, largest_city:Denver, capital:Denver], [id:7, country:USA, name:Connecticut, abbr:CT, area:14357SKM, largest_city:Bridgeport, capital:Hartford], [id:8, country:USA, name:Delaware, abbr:DE, area:6446SKM, largest_city:Wilmington, capital:Dover], [id:9, country:USA, name:Florida, abbr:FL, area:170312SKM, largest_city:Jacksonville, capital:Tallahassee], [id:10, country:USA, name:Georgia, abbr:GA, area:57513SKM, largest_city:Atlanta, capital:Atlanta], [id:11, country:USA, name:Hawaii, abbr:HI, area:6423SKM, largest_city:Honolulu, capital:Honolulu], [id:12, country:USA, name:Idaho, abbr:ID, area:82643SKM, largest_city:Boise, capital:Boise], [id:13, country:USA, name:Illinois, abbr:IL, area:149995SKM, largest_city:Chicago, capital:Springfield], [id:14, country:USA, name:Indiana, abbr:IN, area:35826SKM, largest_city:Indianapolis, capital:Indianapolis], [id:15, country:USA, name:Iowa, abbr:IA, area:55857SKM, largest_city:Des Moines, capital:Des Moines], [id:16, country:USA, name:Kansas, abbr:KS, area:213100SKM, largest_city:Wichita, capital:Topeka], [id:17, country:USA, name:Kentucky, abbr:KY, area:104656SKM, largest_city:Louisville, capital:Frankfort], [id:18, country:USA, name:Louisiana, abbr:LA, area:135659SKM, largest_city:New Orleans, capital:Baton Rouge], [id:19, country:USA, name:Maine, abbr:ME, area:91633SKM, largest_city:Portland, capital:Augusta], [id:20, country:USA, name:Maryland, abbr:MD, area:32131SKM, largest_city:Baltimore, capital:Annapolis], [id:21, country:USA, name:Massachusetts, abbr:MA, area:7800SKM, largest_city:Boston, capital:Boston], [id:22, country:USA, name:Michigan, abbr:MI, area:250487SKM, largest_city:Detroit, capital:Lansing], [id:23, country:USA, name:Minnesota, abbr:MN, area:225163SKM, largest_city:Minneapolis, capital:St. Paul], [id:24, country:USA, name:Mississippi, abbr:MS, area:46923SKM, largest_city:Jackson, capital:Jackson], [id:25, country:USA, name:Missouri, abbr:MO, area:180540SKM, largest_city:Kansas City, capital:Jefferson City], [id:26, country:USA, name:Montana, abbr:MT, area:380831SKM, largest_city:Billings, capital:Helena], [id:27, country:USA, name:Nebraska, abbr:NE, area:200330SKM, largest_city:Omaha, capital:Lincoln], [id:28, country:USA, name:Nevada, abbr:NV, area:286380SKM, largest_city:Las Vegas, capital:Carson City], [id:29, country:USA, name:New Hampshire, abbr:NH, area:24214SKM, largest_city:Manchester, capital:Concord], [id:30, country:USA, name:New Jersey, abbr:NJ, area:22591SKM, largest_city:Newark, capital:Trenton], [id:31, country:USA, name:New Mexico, abbr:NM, area:314917SKM, largest_city:Albuquerque, capital:Santa Fe], [id:32, country:USA, name:New York, abbr:NY, area:141297SKM, largest_city:New York City, capital:Albany], [id:33, country:USA, name:North Carolina, abbr:NC, area:139391SKM, largest_city:Charlotte, capital:Raleigh], [id:34, country:USA, name:North Dakota, abbr:ND, area:183108SKM, largest_city:Fargo, capital:Bismarck], [id:35, country:USA, name:Ohio, abbr:OH, area:40861SKM, largest_city:Columbus, capital:Columbus], [id:36, country:USA, name:Oklahoma, abbr:OK, area:68595SKM, largest_city:Oklahoma City, capital:Oklahoma City], [id:37, country:USA, name:Oregon, abbr:OR, area:254799SKM, largest_city:Portland, capital:Salem], [id:38, country:USA, name:Pennsylvania, abbr:PA, area:119280SKM, largest_city:Philadelphia, capital:Harrisburg], [id:39, country:USA, name:Rhode Island, abbr:RI, area:1034SKM, largest_city:Providence, capital:Providence], [id:40, country:USA, name:South Carolina, abbr:SC, area:82933SKM, largest_city:Charleston, capital:Columbia], [id:41, country:USA, name:South Dakota, abbr:SD, area:199729SKM, largest_city:Sioux Falls, capital:Pierre], [id:42, country:USA, name:Tennessee, abbr:TN, area:41235SKM, largest_city:Nashville, capital:Nashville], [id:43, country:USA, name:Texas, abbr:TX, area:695662SKM, largest_city:Houston, capital:Austin], [id:44, country:USA, name:Utah, abbr:UT, area:82170SKM, largest_city:Salt Lake City, capital:Salt Lake City], [id:45, country:USA, name:Vermont, abbr:VT, area:24906SKM, largest_city:Burlington, capital:Montpelier], [id:46, country:USA, name:Virginia, abbr:VA, area:110787SKM, largest_city:Virginia Beach, capital:Richmond], [id:47, country:USA, name:Washington, abbr:WA, area:184661SKM, largest_city:Seattle, capital:Olympia], [id:48, country:USA, name:West Virginia, abbr:WV, area:24038SKM, largest_city:Charleston, capital:Charleston], [id:49, country:USA, name:Wisconsin, abbr:WI, area:169635SKM, largest_city:Milwaukee, capital:Madison], [id:50, country:USA, name:Wyoming, abbr:WY, area:97093SKM, largest_city:Cheyenne, capital:Cheyenne], [id:51, country:USA, name:American Samoa, abbr:AS, area:1505SKM, capital:Pago Pago], [id:52, country:USA, name:Guam, abbr:GU, area:1478SKM, capital:Hag\u00c3\u00a5t\u00c3\u00b1a], [id:53, country:USA, name:Northern Mariana Islands, abbr:MP, area:5117SKM, capital:Saipan], [id:54, country:USA, name:Puerto Rico, abbr:PR, area:13791SKM, capital:San Juan], [id:55, country:USA, name:U.S. Virgin Islands, abbr:VI, area:1898SKM, capital:Charlotte Amalie]]<\/pre>\n<h2 class=\"wp-block-heading\" id=\"h-8-summary\"><a name=\"heading8\"><\/a>8. Summary<\/h2>\n<p>In this example, we built a Spring Boot application with Groovy to demonstrate the integration between Spring and Groovy. We also demonstrated that Groovy source code is shorter and cleaner than Java. But Java is faster than Groovy.<\/p>\n<h2 class=\"wp-block-heading\" id=\"h-9-references\"><a name=\"heading9\"><\/a>9. References<\/h2>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/dzone.com\/articles\/spring-4-groovy\" target=\"_blank\" rel=\"noopener\">https:\/\/dzone.com\/articles\/spring-4-groovy<\/a><\/li>\n<li><a href=\"https:\/\/o7planning.org\/en\/11799\/spring-boot-and-groovy-tutorial\" target=\"_blank\" rel=\"noopener\">https:\/\/o7planning.org\/en\/11799\/spring-boot-and-groovy-tutorial<\/a><\/li>\n<li><a href=\"https:\/\/objectpartners.com\/2016\/01\/12\/using-groovy-based-spring\" target=\"_blank\" rel=\"noopener\">https:\/\/objectpartners.com\/2016\/01\/12\/using-groovy-based-spring<\/a><\/li>\n<li><a href=\"https:\/\/spring.io\/blog\/2013\/12\/12\/announcing-spring-framework-4-0-ga-release\" target=\"_blank\" rel=\"noopener\">https:\/\/spring.io\/blog\/2013\/12\/12\/announcing-spring-framework-4-0-ga-release<\/a><\/li>\n<li><a href=\"https:\/\/www.javacodegeeks.com\/2013\/01\/spring-dynamic-language-support-with-groovy.html\" target=\"_blank\" rel=\"noopener\">https:\/\/www.javacodegeeks.com\/2013\/01\/spring-dynamic-language-support-with-groovy.html<\/a><\/li>\n<li><a href=\"http:\/\/www.groupkt.com\/post\/f2129b88\/free-restful-web-services-to-consume-and-test.htm\" target=\"_blank\" rel=\"noopener\">http:\/\/www.groupkt.com\/post\/f2129b88\/free-restful-web-services-to-consume-and-test.htm<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\" id=\"h-10-download-the-source-code\"><a name=\"heading10\"><\/a>10. Download the Source Code<\/h2>\n<p>This example consists of a Spring boot application which developed in Groovy.<\/p>\n<div class=\"download\"><strong>Download<\/strong><br \/>You can download the full source code of this example here: <a href=\"http:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2018\/03\/groovy-spring.zip\"><strong>Spring Framework Groovy Tutorial<\/strong><\/a><\/div>\n<p><strong>Last updated on Apr. 29th, 2021<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will explain Spring Framework using Groovy. Spring is a Java application framework that provides many useful services for building applications. It has supported Apache Groovy fully since version 4. In this tutorial, we will build a Spring boot application in Groovy. Table Of Contents 1. Introduction 2. Technologies Used 3. Spring-boot &hellip;<\/p>\n","protected":false},"author":140,"featured_media":1248,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[52],"tags":[982],"class_list":["post-56456","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-spring","tag-groovy"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Spring Framework Groovy Tutorial - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"In this article, we will explain Spring Framework using Groovy. Spring is a Java application framework that provides many useful services for building\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Spring Framework Groovy Tutorial - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"In this article, we will explain Spring Framework using Groovy. Spring is a Java application framework that provides many useful services for building\" \/>\n<meta property=\"og:url\" content=\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"Examples Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2018-04-02T08:00:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-04-29T10:37:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Mary Zheng\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mary Zheng\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/\"},\"author\":{\"name\":\"Mary Zheng\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/8a2034fbabcb20a9396e9819261855ae\"},\"headline\":\"Spring Framework Groovy Tutorial\",\"datePublished\":\"2018-04-02T08:00:35+00:00\",\"dateModified\":\"2021-04-29T10:37:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/\"},\"wordCount\":1170,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/spring-logo.jpg\",\"keywords\":[\"groovy\"],\"articleSection\":[\"spring\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/\",\"url\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/\",\"name\":\"Spring Framework Groovy Tutorial - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/spring-logo.jpg\",\"datePublished\":\"2018-04-02T08:00:35+00:00\",\"dateModified\":\"2021-04-29T10:37:08+00:00\",\"description\":\"In this article, we will explain Spring Framework using Groovy. Spring is a Java application framework that provides many useful services for building\",\"breadcrumb\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#primaryimage\",\"url\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/spring-logo.jpg\",\"contentUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/spring-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/examples.javacodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java Development\",\"item\":\"https:\/\/examples.javacodegeeks.com\/category\/java-development\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\/\/examples.javacodegeeks.com\/category\/java-development\/enterprise-java\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"spring\",\"item\":\"https:\/\/examples.javacodegeeks.com\/category\/java-development\/enterprise-java\/spring\/\"},{\"@type\":\"ListItem\",\"position\":5,\"name\":\"Spring Framework Groovy Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#website\",\"url\":\"https:\/\/examples.javacodegeeks.com\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Examples and Code Snippets\",\"publisher\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/examples.javacodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/examples.javacodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/javacodegeeks\",\"https:\/\/x.com\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/8a2034fbabcb20a9396e9819261855ae\",\"name\":\"Mary Zheng\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2017\/11\/Mary-Zheng_avatar_1510732235-96x96.jpg\",\"contentUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2017\/11\/Mary-Zheng_avatar_1510732235-96x96.jpg\",\"caption\":\"Mary Zheng\"},\"description\":\"Mary has graduated from Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She works as a senior Software Engineer in the telecommunications sector where she acts as a leader and works with others to design, implement, and monitor the software solution.\",\"url\":\"https:\/\/examples.javacodegeeks.com\/author\/mary-zheng\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Spring Framework Groovy Tutorial - Java Code Geeks","description":"In this article, we will explain Spring Framework using Groovy. Spring is a Java application framework that provides many useful services for building","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/","og_locale":"en_US","og_type":"article","og_title":"Spring Framework Groovy Tutorial - Java Code Geeks","og_description":"In this article, we will explain Spring Framework using Groovy. Spring is a Java application framework that provides many useful services for building","og_url":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/","og_site_name":"Examples Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2018-04-02T08:00:35+00:00","article_modified_time":"2021-04-29T10:37:08+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Mary Zheng","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Mary Zheng","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#article","isPartOf":{"@id":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/"},"author":{"name":"Mary Zheng","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/8a2034fbabcb20a9396e9819261855ae"},"headline":"Spring Framework Groovy Tutorial","datePublished":"2018-04-02T08:00:35+00:00","dateModified":"2021-04-29T10:37:08+00:00","mainEntityOfPage":{"@id":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/"},"wordCount":1170,"commentCount":0,"publisher":{"@id":"https:\/\/examples.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/spring-logo.jpg","keywords":["groovy"],"articleSection":["spring"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/","url":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/","name":"Spring Framework Groovy Tutorial - Java Code Geeks","isPartOf":{"@id":"https:\/\/examples.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#primaryimage"},"image":{"@id":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/spring-logo.jpg","datePublished":"2018-04-02T08:00:35+00:00","dateModified":"2021-04-29T10:37:08+00:00","description":"In this article, we will explain Spring Framework using Groovy. Spring is a Java application framework that provides many useful services for building","breadcrumb":{"@id":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#primaryimage","url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/spring-logo.jpg","contentUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/spring-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/examples.javacodegeeks.com\/spring-framework-groovy-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/examples.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java Development","item":"https:\/\/examples.javacodegeeks.com\/category\/java-development\/"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/examples.javacodegeeks.com\/category\/java-development\/enterprise-java\/"},{"@type":"ListItem","position":4,"name":"spring","item":"https:\/\/examples.javacodegeeks.com\/category\/java-development\/enterprise-java\/spring\/"},{"@type":"ListItem","position":5,"name":"Spring Framework Groovy Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/examples.javacodegeeks.com\/#website","url":"https:\/\/examples.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Examples and Code Snippets","publisher":{"@id":"https:\/\/examples.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/examples.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/examples.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/examples.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/8a2034fbabcb20a9396e9819261855ae","name":"Mary Zheng","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2017\/11\/Mary-Zheng_avatar_1510732235-96x96.jpg","contentUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2017\/11\/Mary-Zheng_avatar_1510732235-96x96.jpg","caption":"Mary Zheng"},"description":"Mary has graduated from Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She works as a senior Software Engineer in the telecommunications sector where she acts as a leader and works with others to design, implement, and monitor the software solution.","url":"https:\/\/examples.javacodegeeks.com\/author\/mary-zheng\/"}]}},"_links":{"self":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/56456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/users\/140"}],"replies":[{"embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=56456"}],"version-history":[{"count":0,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/56456\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/media\/1248"}],"wp:attachment":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=56456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=56456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=56456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}