Practical example of Hexagonal architecture - add project

This commit is contained in:
Sasa M 2020-04-01 19:18:10 +02:00 committed by Sasa M
parent 3f6c4e6406
commit 63dcae6423
13 changed files with 328 additions and 0 deletions

View File

@ -0,0 +1,73 @@
package com.baeldung.employee.config;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.TransactionManager;
@Configuration
@EnableJpaRepositories(basePackages = "com.baeldung.employee.data", entityManagerFactoryRef = "emf")
@ComponentScan(basePackages = "com.baeldung.employee")
public class AppConfig {
@Bean
public DataSource h2DataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.H2)
.addScript("createEmployeeTable.sql")
.build();
return db;
}
@Bean
public ModelMapper mapper() {
return new ModelMapper();
}
/* @Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
return mapper;
}
*/
@Bean(name = "emf")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.baeldung.employee");
factory.setDataSource(h2DataSource());
// factory.setJpaProperties(jpaProperties());
return factory;
}
@Bean
public TransactionManager jpaTransactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.employee.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class ApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(AppConfig.class);
servletContext.addListener(new ContextLoaderListener(context));
// Create DispatcherServlet
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("EmployeeSpringApp", new DispatcherServlet());
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/app");
}
}

View File

@ -0,0 +1,9 @@
package com.baeldung.employee.data;
import com.baeldung.employee.dto.EmployeeDTO;
public interface EmployeeDataAdapter {
void addEmployee(EmployeeDTO emp);
}

View File

@ -0,0 +1,28 @@
package com.baeldung.employee.data;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.baeldung.employee.domain.Employee;
import com.baeldung.employee.dto.EmployeeDTO;
@Component
public class EmployeeDataAdapterImpl implements EmployeeDataAdapter {
@PersistenceContext
private EntityManager em;
@Autowired
private ModelMapper modelMapper;
@Override
public void addEmployee(EmployeeDTO emp) {
em.persist(modelMapper.map(emp, Employee.class));
}
}

View File

@ -0,0 +1,9 @@
package com.baeldung.employee.data;
import org.springframework.data.jpa.repository.JpaRepository;
import com.baeldung.employee.domain.Employee;
public interface EmployeeRepo extends JpaRepository<Employee, Long> {
}

View File

@ -0,0 +1,43 @@
package com.baeldung.employee.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
public Employee() {
}
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
public long getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// Standard constructors, getters and setters
}

View File

@ -0,0 +1,9 @@
package com.baeldung.employee.dto;
public class EmployeeDTO {
private long id;
private String name;
// Standard constructors, getters and setters
}

View File

@ -0,0 +1,47 @@
package com.baeldung.employee.service;
import java.net.URI;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import com.baeldung.employee.domain.Employee;
@RestController
public class EmployeeController {
@Autowired
private EmployeeService empService;
@GetMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE)
public String home() {
return "This is employee app page";
}
@PostMapping(path = "/employees", consumes = "application/json", produces = "application/json")
public ResponseEntity<Object> addEmployee(@RequestBody Map<String, String> empBody) {
String id = empBody.get("id");
String name = empBody.get("name");
Employee emp = new Employee(Integer.valueOf(id), name);
empService.addEmployee(emp);
// Create resource uri
URI uri = ServletUriComponentsBuilder.fromCurrentRequest()
.buildAndExpand(emp.getId())
.toUri();
// Send uri in response
return ResponseEntity.created(uri)
.build();
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.employee.service;
import com.baeldung.employee.domain.Employee;
public interface EmployeeService {
void addEmployee(Employee emp);
}

View File

@ -0,0 +1,25 @@
package com.baeldung.employee.service;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baeldung.employee.data.EmployeeDataAdapter;
import com.baeldung.employee.domain.Employee;
import com.baeldung.employee.dto.EmployeeDTO;
@Service
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeDataAdapter employeeDataAdapter;
@Autowired
private ModelMapper modelMapper;
@Override
public void addEmployee(Employee emp) {
employeeDataAdapter.addEmployee(modelMapper.map(emp, EmployeeDTO.class));
}
}

View File

@ -0,0 +1,11 @@
DROP TABLE IF EXISTS EMPLOYEE;
CREATE TABLE EMPLOYEE (
ID IDENTITY PRIMARY KEY,
NAME VARCHAR(64) NOT NULL,
);
INSERT INTO EMPLOYEE (ID, NAME) VALUES (10, 'EMP 10');
INSERT INTO EMPLOYEE (ID, NAME) VALUES (20, 'EMP 20');

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:component-scan base-package="com.baeldung.employee.*"/>
</beans>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>Employee Spring App</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>EmployeeSpringApp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>EmployeeSpringApp</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>