Problem Description: as a rookie, in the process of learning spring boot, I want to watch the teacher's video once and knock myself to impress myself a little bit. As a result, the problem comes. @The Reference of the Reference annotation reported a null pointer exception. After more than two hours of torture and consulting numerous materials, I finally found that my understanding of IOC was not thorough enough, which led to this avoidable mistake.
This article is to record the process and alert yourself. If any God finds that the description is wrong, please correct it. Thank you.
The environment used is as follows:
- JDK1.8
- SpringBoot 2.2.5
- Dubbo 0.2.0(Alibaba)
- Latest version pulled from Zookeeper Docker (3.5.6)
Attach the service provider and service consumer directory structure first
Note: because the @ Reference annotation is used in the consumer, this annotation creates the corresponding instance object through the reflection mechanism through the fully qualified class name, so there must be a directory structure consistent with the service interface provided by the provider in the consumer directory structure.
Attach service provider's code
- Startup class
//@EnableDubbo is equivalent to configuring dubbo.scan.base-packages in the configuration file //Error may be reported if not configured: No provider available from registry @EnableDubbo @SpringBootApplication public class ProviderTicketApplication { public static void main(String[] args) { SpringApplication.run(ProviderTicketApplication.class, args); } }
- Service provided interfaces and interface implementation classes
public interface TicketService { public String getTicket(); } //Here, we must introduce Dubbo's Service annotation. Dubbo will register the interface class of this annotation implementation class with the fully qualified class name in zookeeper import com.alibaba.dubbo.config.annotation.Service; import com.ittx.ticket.service.TicketService; import org.springframework.stereotype.Component; @Component//Dubbo's Service does not have the ability to configure this class as a Bean object, so this annotation is needed @Service(version = "${dubbo.application.version}") public class TicketServiceImpl implements TicketService { @Override public String getTicket() { return "<Great, my country"; } }
- Service provider profile
# The name must be the same as the project name dubbo.application.name=provider-ticket # The following two can be written as one: dubbo.registry.address=zookeeper://192.168.160.128:2181 dubbo.registry.address=192.168.160.128:2181 dubbo.registry.protocol=zookeeper dubbo.protocol.name=dubbo dubbo.protocol.port=20880 # Scan the package name of the interface to register the service. The package name + interface name form the fully qualified class name dubbo.scan.base-packages=com.ittx.ticket.service dubbo.consumer.check=false dubbo.application.version=3
Consumer code:
==TickerService in consumer code is the same as provider code==
- Consumer services
import com.alibaba.dubbo.config.annotation.Reference; import com.ittx.ticket.service.TicketService; import org.springframework.stereotype.Service; @Service public class ConsumerService { @Reference(check = false, version = "3")//Remote call, the registration name of TicketService is used by default. This service is included in the remote service TicketService ticketService; public void hello(){ String ticket = ticketService.getTicket(); System.out.println("Tickets are available." + ticket); } }
- Consumer profile
dubbo.registry.address=192.168.160.128:2181 dubbo.application.name=comsumer dubbo.registry.protocol=zookeeper # server.port=8081
- Test code (here's the problem)
@SpringBootTest class ComsumerApplicationTests { @Autowired ConsumerService consumerService; @Test void contextLoads() { //The problem is in the following line of code: //ConConsumerService service = new ConsumerService(); //service.hello(); consumerService.hello(); } }
Because I did not use dependency injection according to the traditional idea of creating objects, I created a new ConsumerService object. This way is outside the spring boot framework, completely avoiding the IOC container, and @ Reference belongs to the spring boot framework. In the newly created service and execute @ Reference annotation, the ticketService member variable in it is actually null.
Harvest:
- I saw a lot of good blogs when I looked up the materials today, which explained that @ Reference may be empty in spring MVC. Please refer to Deep analysis of the problem in which the reference annotation of dubbo is empty in the controller,Dubbo client call error NullPointerException using zookeeper
- Learn to view zookeeper files to view registered services:
docker exec -it container ID /bin/bash #Enter corresponding documents ./bin/zkCli.sh #see file ls /dubbo #Can view registered services
- If the console reports an error: Will not attempt to authenticate using SASL (unknown error). It may also be the problem of zookeeper address mapping. You can add the mapping to the hosts file: the container name in the server IP docker (in this way, the corresponding address property values of consumers and providers need to change the IP address to the container name)