Κοινή χρήση τεχνολογίας

Επίδειξη γρήγορης εκκίνησης με ενσωματωμένο Spring Boot

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1.Τι είναι το RMI;

Το RMI (Remote Method Invocation) είναι η απομακρυσμένη επίκληση μεθόδου, η οποία είναι μια βασική ιδέα στον κατανεμημένο προγραμματισμό. Υπάρχουν πολλές τεχνολογίες για την εφαρμογή απομακρυσμένης επίκλησης μεθόδων, όπως το CORBA και το WebService, και οι δύο είναι ανεξάρτητες από κάθε γλώσσα προγραμματισμού. Το Java RMI είναι ένας μηχανισμός κλήσης απομακρυσμένης μεθόδου ειδικά σχεδιασμένος για το περιβάλλον Java. Είναι ένα Java API που χρησιμοποιείται για την υλοποίηση κλήσης απομακρυσμένης διαδικασίας (RPC). Η υλοποίησή του εξαρτάται από το JVM, επομένως υποστηρίζει κλήσεις από το ένα JVM στο άλλο. Στο Java RMI, ο απομακρυσμένος διακομιστής υλοποιεί συγκεκριμένες μεθόδους Java και παρέχει διασυνδέσεις. Έτσι, η συνήθης εκμετάλλευση των τρωτών σημείων αποζερικοποίησης συχνά περιλαμβάνει RMI, και αυτό σημαίνει. Το πρωτόκολλο επικοινωνίας στο οποίο βασίζεται η RMI είναι το JRMP (Java Remote Message Protocol, Java Remote Message Exchange Protocol) Αυτό το πρωτόκολλο είναι προσαρμοσμένο για Java και απαιτεί τόσο ο διακομιστής όσο και ο πελάτης να είναι γραμμένοι σε Java.

διαδραστική διαδικασία

rmi_architecture

αρχείο

Η διαδικασία αλληλεπίδρασης μπορεί να συνοψιστεί ως εξής:

  1. Αρχικά, ξεκινήστε την υπηρεσία μητρώου RMI Κατά την εκκίνηση, μπορείτε να καθορίσετε τη θύρα στην οποία ακούει η υπηρεσία ή μπορείτε να χρησιμοποιήσετε την προεπιλεγμένη θύρα (1099).
  2. Δεύτερον, η πλευρά του διακομιστή εγκαινιάζει πρώτα μια κλάση υλοποίησης που παρέχει υπηρεσίες τοπικά και, στη συνέχεια, καταχωρεί την κλάση υλοποίησης που μόλις παρουσιάστηκε στο μητρώο RMI μέσω της μεθόδου bind ή rebind της κλάσης Naming/Context/Registry που παρέχεται από την RMI και την εκθέτει προς τα έξω. κόσμος.
  3. Τέλος, ο πελάτης χρησιμοποιεί την τοπική διεπαφή και ένα γνωστό όνομα (δηλαδή, το όνομα που εκτίθεται από το μητρώο RMI) για να λάβει την κλάση υλοποίησης από την υπηρεσία RMI χρησιμοποιώντας τη μέθοδο αναζήτησης της κλάσης Naming/Context/Registry που παρέχεται από την RMI. Με αυτόν τον τρόπο, αν και δεν υπάρχει κλάση υλοποίησης αυτής της κλάσης τοπικά, όλες οι μέθοδοι βρίσκονται στη διεπαφή και οι μέθοδοι του αντικειμένου μπορούν να καλούνται εξ αποστάσεως.

2. Μηχανική κωδικών

Πειραματικοί στόχοι

Πειραματιστείτε με μια απλή υπηρεσία rmi και καλέστε την μέσω του πελάτη

rmi-server

Αυτό είναι ένα έργο από την πλευρά του διακομιστή που παρέχει κυρίως διασύνδεση υπηρεσιών rmi

pom.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>rmi</artifactId>
  7. <groupId>com.et</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>rmi-server</artifactId>
  12. <properties>
  13. <maven.compiler.source>8</maven.compiler.source>
  14. <maven.compiler.target>8</maven.compiler.target>
  15. </properties>
  16. <dependencies>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-web</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-autoconfigure</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-test</artifactId>
  28. <scope>test</scope>
  29. </dependency>
  30. <dependency>
  31. <groupId>org.springframework.boot</groupId>
  32. <artifactId>spring-boot-starter-data-jpa</artifactId>
  33. </dependency>
  34. <dependency>
  35. <groupId>com.et</groupId>
  36. <artifactId>rmi-common</artifactId>
  37. <version>1.0-SNAPSHOT</version>
  38. </dependency>
  39. <dependency>
  40. <groupId>com.h2database</groupId>
  41. <artifactId>h2</artifactId>
  42. <version>1.4.200</version>
  43. </dependency>
  44. </dependencies>
  45. </project>
config
  1. package com.et.rmi.server.config;
  2. import com.et.rmi.server.dao.CustomerRepository;
  3. import com.et.rmi.server.model.Customer;
  4. import com.et.rmi.server.service.CustomerServiceImpl;
  5. import om.et.rmi.common.CustomerService;
  6. import org.springframework.boot.ApplicationArguments;
  7. import org.springframework.boot.ApplicationRunner;
  8. import org.springframework.context.annotation.Bean;
  9. import org.springframework.remoting.rmi.RmiServiceExporter;
  10. import org.springframework.stereotype.Component;
  11. import java.util.logging.Logger;
  12. @Component
  13. public class RmiServerApplicationRunner implements ApplicationRunner {
  14. private CustomerRepository repository;
  15. private CustomerServiceImpl customerService;
  16. private final Logger log = Logger.getLogger(this.getClass().getName());
  17. public RmiServerApplicationRunner(CustomerServiceImpl customerService) {
  18. this.customerService = customerService;
  19. }
  20. @Override
  21. public void run(ApplicationArguments args) throws Exception {
  22. Customer customer1 = new Customer("John", "Smith", "123-456-7890");
  23. customerService.saveCustomer(customer1);
  24. customerService.getCustomers().forEach(System.out::println);
  25. }
  26. @Bean
  27. public RmiServiceExporter customerServiceExporter() {
  28. RmiServiceExporter customerServiceExporter = new RmiServiceExporter();
  29. customerServiceExporter.setRegistryPort(1199);
  30. customerServiceExporter.setServiceName("customerService");
  31. customerServiceExporter.setServiceInterface(CustomerService.class);
  32. customerServiceExporter.setService(customerService);
  33. log.info("Started RMI Server");
  34. return customerServiceExporter;
  35. }
  36. }
υπηρεσία
  1. package com.et.rmi.server.service;
  2. import com.et.rmi.server.dao.CustomerRepository;
  3. import com.et.rmi.server.mapper.CustomerMapper;
  4. import com.et.rmi.server.model.Customer;
  5. import om.et.rmi.common.CustomerDTO;
  6. import om.et.rmi.common.CustomerService;
  7. import org.springframework.stereotype.Service;
  8. import java.util.List;
  9. @Service
  10. public class CustomerServiceImpl implements CustomerService {
  11. private CustomerRepository repository;
  12. public CustomerServiceImpl(CustomerRepository repository) {
  13. this.repository = repository;
  14. }
  15. @Override
  16. public CustomerDTO getCustomer(long id) {
  17. Customer customer = repository.findById(id).orElseThrow(IllegalArgumentException::new);
  18. CustomerMapper mapper = new CustomerMapper();
  19. CustomerDTO dto = mapper.mapToDTO(customer);
  20. System.out.println(dto);
  21. return dto;
  22. }
  23. public List<Customer> getCustomers() {
  24. return (List<Customer>)repository.findAll();
  25. }
  26. public void saveCustomer(Customer customer) {
  27. repository.save(customer);
  28. }
  29. }
ντάο
  1. package com.et.rmi.server.dao;
  2. import com.et.rmi.server.model.Customer;
  3. import org.springframework.data.repository.CrudRepository;
  4. import org.springframework.stereotype.Repository;
  5. import java.util.Optional;
  6. @Repository
  7. public interface CustomerRepository extends CrudRepository<Customer, Long> {
  8. Optional<Customer> findById(long id);
  9. }
χαρτογράφος
  1. package com.et.rmi.server.mapper;
  2. import com.et.rmi.server.model.Customer;
  3. import om.et.rmi.common.CustomerDTO;
  4. public class CustomerMapper {
  5. public CustomerMapper() {
  6. }
  7. public CustomerDTO mapToDTO(Customer customer){
  8. CustomerDTO dto = new CustomerDTO();
  9. dto.setFirstName(customer.getFirstName());
  10. dto.setLastName(customer.getLastName());
  11. dto.setSocialSecurityCode(customer.getSocialSecurityCode());
  12. return dto;
  13. }
  14. }
μοντέλο
  1. package com.et.rmi.server.model;
  2. import javax.persistence.*;
  3. @Entity
  4. @SequenceGenerator(name = "CUST_SEQ", initialValue = 1_000_001)
  5. public class Customer {
  6. @Id
  7. @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CUST_SEQ")
  8. private long id;
  9. private String firstName;
  10. private String lastName;
  11. private String socialSecurityCode;
  12. public Customer() {
  13. }
  14. public Customer(String firstName, String lastName, String socialSecurityCode) {
  15. this.firstName = firstName;
  16. this.lastName = lastName;
  17. this.socialSecurityCode = socialSecurityCode;
  18. }
  19. public long getId() {
  20. return id;
  21. }
  22. public String getFirstName() {
  23. return firstName;
  24. }
  25. public void setFirstName(String firstName) {
  26. this.firstName = firstName;
  27. }
  28. public String getLastName() {
  29. return lastName;
  30. }
  31. public void setLastName(String lastName) {
  32. this.lastName = lastName;
  33. }
  34. public String getSocialSecurityCode() {
  35. return socialSecurityCode;
  36. }
  37. public void setSocialSecurityCode(String socialSecurityCode) {
  38. this.socialSecurityCode = socialSecurityCode;
  39. }
  40. @Override
  41. public String toString() {
  42. return "Customer{" +
  43. "id=" + id +
  44. ", firstName='" + firstName + ''' +
  45. ", lastName='" + lastName + ''' +
  46. ", socialSecurityCode='" + socialSecurityCode + ''' +
  47. '}';
  48. }
  49. }
εφαρμογή.ιδιότητες
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect

rmi-πελάτης

Αυτό είναι ένα έργο πελάτη, το οποίο καλεί κυρίως την απομακρυσμένη υπηρεσία rmi.

pom.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>rmi</artifactId>
  7. <groupId>com.et</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>rmi-cilent</artifactId>
  12. <properties>
  13. <maven.compiler.source>8</maven.compiler.source>
  14. <maven.compiler.target>8</maven.compiler.target>
  15. </properties>
  16. <dependencies>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-web</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-autoconfigure</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-test</artifactId>
  28. <scope>test</scope>
  29. </dependency>
  30. <dependency>
  31. <groupId>com.et</groupId>
  32. <artifactId>rmi-common</artifactId>
  33. <version>1.0-SNAPSHOT</version>
  34. </dependency>
  35. </dependencies>
  36. </project>
ελεγκτής
  1. package com.et.rmi.client.controller;
  2. import om.et.rmi.common.CustomerDTO;
  3. import om.et.rmi.common.CustomerService;
  4. import org.springframework.http.MediaType;
  5. import org.springframework.http.ResponseEntity;
  6. import org.springframework.remoting.rmi.RmiProxyFactoryBean;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.web.bind.annotation.PathVariable;
  9. import org.springframework.web.bind.annotation.RequestMapping;
  10. import org.springframework.web.bind.annotation.RequestMethod;
  11. @Controller
  12. @RequestMapping(value = "customers")
  13. public class CustomerController {
  14. private RmiProxyFactoryBean proxyFactoryBean;
  15. public CustomerController(RmiProxyFactoryBean proxyFactoryBean) {
  16. this.proxyFactoryBean = proxyFactoryBean;
  17. }
  18. @RequestMapping(value = "{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
  19. public ResponseEntity<CustomerDTO> getCustomer(@PathVariable long id) {
  20. CustomerService service = (CustomerService) proxyFactoryBean.getObject();
  21. CustomerDTO dto = service.getCustomer(id);
  22. return ResponseEntity.ok(dto);
  23. }
  24. }
config
  1. package com.et.rmi.client.config;
  2. import om.et.rmi.common.CustomerService;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.remoting.rmi.RmiProxyFactoryBean;
  5. import org.springframework.stereotype.Component;
  6. import org.springframework.util.StringUtils;
  7. import java.util.logging.Logger;
  8. @Component
  9. public class Config {
  10. public final Logger log = Logger.getLogger(this.getClass().getName());
  11. @Bean
  12. public RmiProxyFactoryBean proxyFactoryBean() {
  13. String remoteHost = System.getProperty("RMI_SERVER_HOST");
  14. if(StringUtils.isEmpty(remoteHost)){
  15. remoteHost="127.0.0.1";
  16. }
  17. String rmiHost = String.format("rmi://%s:1199/customerService", remoteHost);
  18. log.info("RMI Host name is " + rmiHost);
  19. RmiProxyFactoryBean proxy = new RmiProxyFactoryBean();
  20. proxy.setServiceInterface(CustomerService.class);
  21. proxy.setServiceUrl(rmiHost);
  22. proxy.afterPropertiesSet();
  23. return proxy;
  24. }
  25. }
εφαρμογή.ιδιότητες
server.port=8081

rmi-κοινή

Αυτό είναι ένα δημόσιο πακέτο στο οποίο πρέπει να αναφέρονται τόσο ο διακομιστής όσο και ο πελάτης.

  1. package om.et.rmi.common;
  2. import java.io.Serializable;
  3. public class CustomerDTO implements Serializable {
  4. private String firstName;
  5. private String lastName;
  6. private String socialSecurityCode;
  7. public CustomerDTO() {
  8. }
  9. public String getFirstName() {
  10. return firstName;
  11. }
  12. public void setFirstName(String firstName) {
  13. this.firstName = firstName;
  14. }
  15. public String getLastName() {
  16. return lastName;
  17. }
  18. public void setLastName(String lastName) {
  19. this.lastName = lastName;
  20. }
  21. public String getSocialSecurityCode() {
  22. return socialSecurityCode;
  23. }
  24. public void setSocialSecurityCode(String socialSecurityCode) {
  25. this.socialSecurityCode = socialSecurityCode;
  26. }
  27. @Override
  28. public String toString() {
  29. final StringBuffer sb = new StringBuffer("CustomerDTO{");
  30. sb.append("firstName='").append(firstName).append(''');
  31. sb.append(", lastName='").append(lastName).append(''');
  32. sb.append(", socialSecurityCode='").append(socialSecurityCode).append(''');
  33. sb.append('}');
  34. return sb.toString();
  35. }
  36. }
  1. package om.et.rmi.common;
  2. public interface CustomerService {
  3. CustomerDTO getCustomer(long id);
  4. }

Τα παραπάνω είναι μόνο μερικοί κωδικοί κλειδιών Για όλους τους κωδικούς, ανατρέξτε στο αποθετήριο κωδικών παρακάτω.

αποθήκη κωδικών

3. Δοκιμή

  • Ξεκινήστε την υπηρεσία rmi-server
  • Ξεκινήστε την υπηρεσία rmi-client
  • Επισκεφτείτε τη διεύθυνση http://127.0.0.1:8081/customers/1000001
  • ΕΠΙΣΤΡΟΦΗ{"firstName":"John","lastName":"Smith","socialSecurityCode":"123-456-7890"}

4. Παράθεση