package com.wanshi.netty.dubborpc.netty;
public class SubjectImpl implements Subject{
@Override
public String buy(String msg) {
return "买了" + msg;
}
}
ProxySubject类
package com.wanshi.netty.dubborpc.netty;
public class ProxySubject {
private Subject subject;
{
subject = new SubjectImpl();
}
public void buy(String msg) {
System.out.println("美团外卖,使命必达,跑腿代买!");
String buy = subject.buy(msg);
System.out.println(buy);
}
}
测试类
public static void main(String[] args) {
ProxySubject subject = new ProxySubject();
subject.buy("北京烤鸭");
}
效果
⛽静态代理的优缺点
缺点: 不利于扩展,调用一次就要创建一次对象,从而造成不必要的内存空间浪费
优点: 可读性好,逻辑简单,清晰明了
动态代理又分为:JDK动态代理、CGLIB动态代理
在程序运行时,运用反射机制动态创建而成,达到调用服务
使用以上的Subject类和实现类
SubjectInvocationHandler处理器类
package com.wanshi.netty.dubborpc.netty;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class SubjectInvocationHandler implements InvocationHandler {
private Object obj;
public SubjectInvocationHandler(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res = method.invoke(obj, args);
return res;
}
}
ProxyFactry工厂类
package com.wanshi.netty.dubborpc.netty;
import java.lang.reflect.Proxy;
public class ProxyFactry {
public static Subject getInstance() {
SubjectImpl subject = new SubjectImpl();
System.out.println("美团外卖,使命必达,跑腿代买!");
SubjectInvocationHandler subjectInvocationHandler = new SubjectInvocationHandler(subject);
Subject proxy = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(),
subject.getClass().getInterfaces(), subjectInvocationHandler);
return proxy;
}
}
测试类
public static void main(String[] args) {
Subject subject = ProxyFactry.getInstance();
String buy = subject.buy("饮料");
System.out.println(buy);
}
效果
⛽动态代理的优缺点
两种动态代理对照表
| | JDK原生动态代理 | CGLIB动态代理 |
| — | — | — |
| 核心原理 | 基于 ”接口实现“方式 | 基于类集成方式 |
| 优点 | Java原生支持的,不需要任何依赖 | 对与代理的目标对象无限制,无需实现接口 |
| 不足之处 | 只能基于接口实现 | 无法处理final方法 |
| 实现方式 | Java原生支持 | 需要引入Jar文件依赖 |
====================================================================================
-
dubbo 底层使用了Netty作为网络通讯框架,要求用Netty实现一个简单的RPC框架
-
模仿dubbo,消费者和提供者约定接口和协议,消费者远程调用提供者的服务,提供者返回一个字符串,消费者打印提供者返回的数据,底层使用Netty框架
-
创建接口,定义抽象方法,用于服务消费者与服务提供者之间的约定
-
创建一个提供者,该类需要监听消费者的请求,并按照约定返回数据
-
创建一个消费者,该类需要 透明的调用自己不存在的方法,内部使用Netty 请求提供者返回数据
♻️共用接口API
HelloService
package com.wanshi.netty.dubborpc.publicinterface;
/**
* 公共接口,提供服务
*/
public interface HelloService {
String hello(String msg);
}
♻️服务提供者
ServerBootstrap启动类
package com.wanshi.netty.dubborpc.provider;
import com.wanshi.netty.dubborpc.netty.NettyServer;
/**
* 服务提供者启动类,监听消费者,并绑定端口8888
*/
public class ServerBootstrap {
public static void main(String[] args) {
NettyServer.startServer("127.0.0.1", 8888);
}
}
NettyServer
package com.wanshi.netty.dubborpc.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
/**
* Netty服务器类,启动服务
*/
public class NettyServer {
/**
* 开启服务方法,调用内部私有启动服务方法,此类写法很常用,进一层的封装了API
* @param hostName
* @param port
*/
public static void startServer(String hostName, int port) {
startServer0(hostName, port);
}
/**
* 真正启动服务的方法
* @param hostName
* @param port
*/
private static void startServer0(String hostName, int port) {
//创建2个线程,一个为主线程仅创建1个,另外创建工作线程CPU核数*2个
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//服务器启动类
ServerBootstrap serverBootstrap = new ServerBootstrap();
//初始化参数
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new NettyServerHandler());
}
});
System.out.println("服务端提供服务准备就绪...");
//绑定端口,启动服务,异步执行方法
ChannelFuture channelFuture = serverBootstrap.bind(hostName, port).sync();
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
//优雅的关闭线程
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
♻️服务消费者
ClientBootstrap
package com.wanshi.netty.dubborpc.consumer;
import com.wanshi.netty.dubborpc.netty.NettyClient;
import com.wanshi.netty.dubborpc.publicinterface.HelloService;
public class ClientBootstrap {
public static final String providerName = "hello#";
public static void main(String[] args) throws InterruptedException {
NettyClient client = new NettyClient();
HelloService service = (HelloService) client.getBean(HelloService.class, providerName);
for (;;) {
Thread.sleep(2000);
String hello = service.hello("你好鸭 dubbo~");
System.out.println("服务端返回的结果:" + hello + "\n\n");
}
}
}
NettyClient
package com.wanshi.netty.dubborpc.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import java.lang.reflect.Proxy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NettyClient {
# 分享
这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!
![薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了](https://img-blog.csdnimg.cn/img_convert/c58b0a6748bedf1d2a6bef6deb42a20a.webp?x-oss-process=image/format,png)
Spring Cloud实战
![薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了](https://img-blog.csdnimg.cn/img_convert/4dd483a7ebf2c84f0e0a45569d75d710.webp?x-oss-process=image/format,png)
Spring Boot实战
![薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了](https://img-blog.csdnimg.cn/img_convert/9048c622c0b9665ac9cd6fea220d83bb.webp?x-oss-process=image/format,png)
面试题整理(性能优化+微服务+并发编程+开源框架+分布式)
.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import java.lang.reflect.Proxy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NettyClient {
# 分享
这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!
[外链图片转存中...(img-HFPozgHq-1714430820406)]
Spring Cloud实战
[外链图片转存中...(img-7dcf9D4E-1714430820407)]
Spring Boot实战
[外链图片转存中...(img-CFQ8MavC-1714430820407)]
面试题整理(性能优化+微服务+并发编程+开源框架+分布式)
> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/topics/618154847)收录**