记一次netty的使用

我不是女神ヾ 2021-09-21 15:50 449阅读 0赞

前言:笔者在项目中使用的netty的场景是这样的,(物联网公司)所有机柜使用长连接连接到服务器,而服务器使用的正好是netty,所以不得已笔者需要学习netty的一些知识,这里只是浅浅的使用笔记,更深入的知识需要后期学习。这里是一个简单使用的笔记

准备:集成netty项目,需要准备好一个能访问使用的项目(略)

1:pom.xml文件(笔者认为所有项目第一步)导入netty的jar包

  1. <!--netty start-->
  2. <dependency>
  3. <groupId>io.netty</groupId>
  4. <artifactId>netty-all</artifactId>
  5. <version>4.1.6.Final</version>
  6. <scope>compile</scope>
  7. </dependency>
  8. <!--netty end-->

因为业务需要有一些json的使用,所以还需要json的jar包,如果没有json需求可以不使用用其它代替也可

  1. <!--fastjson start-->
  2. <dependency>
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>fastjson</artifactId>
  5. <version>1.2.3</version>
  6. </dependency>
  7. <!--fastjson end-->

2:开发netty的主要几个文件,这里分别是ServerHandler,ServerMain,NettyProperties,NettyConfig,业务类的主要几个文件ReturnInfo,ExecuteService和其它业务类等

netty部分代码

ServerHandler类

  1. package com.xiaomage.crm.netty;
  2. import com.xiaomage.crm.taskQueue.SpringContextUtil;
  3. import io.netty.channel.Channel;
  4. import io.netty.channel.ChannelHandlerContext;
  5. import io.netty.channel.ChannelInboundHandlerAdapter;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. /**
  9. * @version V1.0
  10. * @Title: netty服务器处理消息的类
  11. * @date: 2019/3/18 15:53
  12. */
  13. public class ServerHandler extends ChannelInboundHandlerAdapter{
  14. //日志
  15. protected static Logger logger = LoggerFactory.getLogger(ServerHandler.class);
  16. /**
  17. * 客户端与服务端创建连接的时候调用
  18. * 只发生在第一次连接,后续发送消息不再连接
  19. */
  20. @Override
  21. public void channelActive(ChannelHandlerContext ctx){
  22. logger.info("client connection start ..." + ctx);
  23. //自己的业务处理保存通道信息
  24. NettyConfig.addTemporary_Channel(ctx.channel());
  25. }
  26. /**
  27. * 客户端与服务端断开连接时调用
  28. */
  29. @Override
  30. public void channelInactive(ChannelHandlerContext ctx){
  31. logger.info("client close ..." + ctx);
  32. //自己的业务处理清除通道信息
  33. NettyConfig.removeClient(ctx.channel());
  34. }
  35. /**
  36. * 工程出现异常的时候调用
  37. * 异常处理逻辑
  38. */
  39. @Override
  40. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){
  41. String line="server exceptionCaught method run:"+cause.getMessage();
  42. if (NettyProperties.loggerDebugger) {
  43. logger.info("exceptionCaught:"+line);
  44. }
  45. NettyConfig.removeClient(ctx.channel());
  46. //连接已经断开
  47. ctx.close();
  48. }
  49. /**
  50. * 服务端处理客户端socket请求的核心方法,这里接收了客户端发来完整信息
  51. * 业务处理逻辑放在这里 == 格式自己和客户端进行协商,笔者这里是
  52. */
  53. @Override
  54. public void channelRead(ChannelHandlerContext ctx, Object info){
  55. String message = info.toString();
  56. if (NettyProperties.loggerDebugger) {
  57. logger.info("read:"+message);
  58. }
  59. //截取制定字符串,判断类型
  60. int T_index = -1;
  61. if((T_index=message.indexOf("\"T\""))!=-1){
  62. int VCode_index = T_index + 4;
  63. String vCode = message.substring(VCode_index, VCode_index+4);
  64. vCode = vCode.replaceAll("\"", "");
  65. vCode = vCode.replaceAll("'", "");
  66. vCode = vCode.trim();
  67. if(!vCode.equalsIgnoreCase("vv") && !vCode.equalsIgnoreCase("vc")){
  68. vCode = vCode.replace("V","v");
  69. }
  70. if(!NettyConfig.VcStart || vCode.equalsIgnoreCase("vc")){
  71. Object res= null;
  72. try {
  73. //动态调用方法 ==BeansUtils spring调用bean对象方法
  74. ExecuteService execute = SpringContextUtil.getBean(vCode,ExecuteService.class);
  75. // 用反射获取
  76. // Object [] params = new Object[2];
  77. // params[0]=ctx.channel();
  78. // params[1]=message;
  79. // res = execute.getClass().getDeclaredMethod("handler", NioSocketChannel.class,String.class).invoke(execute,params);
  80. //直接获取
  81. res = execute.handler(ctx.channel(),message);
  82. }catch (Exception e) {
  83. System.out.println("解析异常跑错"+e.getMessage());
  84. LogErrorMessage(ctx.channel(),e.getMessage(),message,ReturnInfo.ERROR_UNKNOWN);
  85. }
  86. if(res!=null){
  87. String line = res.toString();
  88. ReturnInfo.sendMsg(ctx.channel(),line);
  89. }
  90. }else{
  91. ReturnInfo.sendMsg(ctx.channel(),NettyConfig.VcContent);
  92. ctx.close();
  93. }
  94. }else{
  95. String errorInfo=ReturnInfo.DownStatePackage(ReturnInfo.ERROR_T_IS_NOT_FOUND);
  96. ReturnInfo.sendMsg(ctx.channel(),errorInfo);
  97. }
  98. }
  99. /**
  100. * @param ctx 通道
  101. * @param errMessage 异常信息
  102. * @param channelContent 通道数据
  103. * @param ErrorCode 异常代码
  104. * @Title: 处理异常数据
  105. * @date: 2020/1/9 11:14
  106. * @version V1.0
  107. */
  108. private void LogErrorMessage(Channel ctx, String errMessage, String channelContent, int ErrorCode) {
  109. logger.error("unknown error:"+errMessage+",当前数据:"+channelContent);
  110. String res= ReturnInfo.DownStatePackage(ErrorCode);
  111. ReturnInfo.sendMsg(ctx,res);
  112. }
  113. }

ServerMain类

  1. package com.xiaomage.crm.netty;
  2. import io.netty.bootstrap.ServerBootstrap;
  3. import io.netty.buffer.ByteBuf;
  4. import io.netty.buffer.Unpooled;
  5. import io.netty.channel.ChannelFuture;
  6. import io.netty.channel.ChannelInitializer;
  7. import io.netty.channel.ChannelOption;
  8. import io.netty.channel.EventLoopGroup;
  9. import io.netty.channel.nio.NioEventLoopGroup;
  10. import io.netty.channel.socket.SocketChannel;
  11. import io.netty.channel.socket.nio.NioServerSocketChannel;
  12. import io.netty.handler.codec.DelimiterBasedFrameDecoder;
  13. import io.netty.handler.codec.string.StringDecoder;
  14. import io.netty.handler.timeout.ReadTimeoutHandler;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import org.springframework.stereotype.Component;
  18. import javax.annotation.PostConstruct;
  19. import java.nio.charset.Charset;
  20. import java.util.concurrent.TimeUnit;
  21. /**
  22. * 1. 双线程组
  23. * 2. Bootstrap配置启动信息
  24. * 3. 注册业务处理Handler
  25. * 4. 绑定服务监听端口并启动服务
  26. */
  27. @Component
  28. public class ServerMain {
  29. //日志
  30. protected static Logger logger = LoggerFactory.getLogger(ServerMain.class);
  31. // 监听线程组,监听客户端请求
  32. private EventLoopGroup acceptorGroup = null;
  33. // 处理客户端相关操作线程组,负责处理与客户端的数据通讯
  34. private EventLoopGroup clientGroup = null;
  35. // 服务启动相关配置信息
  36. private ServerBootstrap bootstrap = null;
  37. public ServerMain(){
  38. init();
  39. }
  40. //初始化设置 netty相关模式
  41. private void init(){
  42. acceptorGroup = new NioEventLoopGroup();
  43. clientGroup = new NioEventLoopGroup();
  44. bootstrap = new ServerBootstrap();
  45. // 绑定线程组
  46. bootstrap.group(acceptorGroup, clientGroup);
  47. // 设定通讯模式为NIO
  48. bootstrap.channel(NioServerSocketChannel.class);
  49. // 设定缓冲区大小
  50. bootstrap.option(ChannelOption.SO_BACKLOG, NettyProperties.so_backlog);
  51. // SO_SNDBUF发送缓冲区,SO_RCVBUF接收缓冲区,SO_KEEPALIVE开启心跳监测(保证连接有效)
  52. bootstrap.option(ChannelOption.SO_SNDBUF, NettyProperties.so_sndbuf)
  53. .option(ChannelOption.SO_RCVBUF, NettyProperties.so_rcvbuf)
  54. .option(ChannelOption.SO_KEEPALIVE, true);
  55. }
  56. //netty服务启动的主要方法
  57. public ChannelFuture doAccept(int port) throws InterruptedException{
  58. bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
  59. //tcp连接入口 默认重新initChannel方法
  60. @Override
  61. protected void initChannel(SocketChannel socketChannel) throws Exception {
  62. // 数据分隔符, 定义的数据分隔符一定是一个ByteBuf类型的数据对象。
  63. ByteBuf [] delimiters = new ByteBuf [2];
  64. delimiters[0] = Unpooled.copiedBuffer("\\r\\n".getBytes());
  65. delimiters[1] = Unpooled.copiedBuffer(NettyProperties.CARRIAGE_RETURN.getBytes());
  66. // 处理固定结束标记符号的Handler。这个Handler没有@Sharable注解修饰,
  67. // 必须每次初始化通道时创建一个新对象
  68. // 使用特殊符号分隔处理数据粘包问题,也要定义每个数据包最大长度。netty建议数据有最大长度。
  69. socketChannel.pipeline().addLast(new DelimiterBasedFrameDecoder(NettyProperties.maxFrameLength, true,true,delimiters));
  70. //字符串解码器Handler,会自动处理channelRead方法的msg参数,将ByteBuf类型的数据转换为字符串对象
  71. socketChannel.pipeline().addLast(new StringDecoder(Charset.forName("UTF-8")));
  72. // 定义一个定时断线处理器,当多长时间内,没有任何的可读取数据,自动断开连接。
  73. // 构造参数,就是间隔时长。 默认的单位是秒。
  74. // 自定义间隔时长单位。 new ReadTimeoutHandler(long times, TimeUnit unit);
  75. socketChannel.pipeline().addLast(new ReadTimeoutHandler(NettyProperties.readTimeout, TimeUnit.SECONDS));
  76. //ServerHandler 自定义的处理 netty服务器处理消息类 -- 注册,发送消息,接收消息都在这个类
  77. socketChannel.pipeline().addLast(new ServerHandler());
  78. }
  79. });
  80. ChannelFuture future = bootstrap.bind(port).sync();
  81. return future;
  82. }
  83. //线程组关闭方法
  84. public void release(){
  85. this.acceptorGroup.shutdownGracefully();
  86. this.clientGroup.shutdownGracefully();
  87. }
  88. @PostConstruct
  89. public void start(){
  90. //加载参数
  91. NettyProperties.init();
  92. //使用1个线程启动netty服务
  93. Thread thread = new Thread(new Runnable() {
  94. @Override
  95. public void run() {
  96. ChannelFuture future = null;
  97. ServerMain server = null;
  98. try{
  99. server = new ServerMain();
  100. future = server.doAccept(NettyProperties.port);
  101. logger.info("server started...");
  102. logger.info("启动成功");
  103. future.channel().closeFuture().sync();
  104. }catch(InterruptedException e){
  105. e.printStackTrace();
  106. }finally{
  107. if(null != future){
  108. try {
  109. future.channel().closeFuture().sync();
  110. } catch (InterruptedException e) {
  111. e.printStackTrace();
  112. }
  113. }
  114. //关闭启动类
  115. if(null != server){
  116. server.release();
  117. }
  118. }
  119. }
  120. });
  121. thread.start();
  122. }
  123. }

NettyProperties类

  1. package com.xiaomage.crm.netty;
  2. import java.util.function.Function;
  3. /**
  4. * @version V1.0
  5. * @Title: netty 配置信息
  6. * @Description: //netty 配置信息
  7. * @date: 2019/9/24 14:31
  8. */
  9. public class NettyProperties {
  10. public static int port=9999; // 监听端口
  11. public static int so_backlog=1024; // 设定缓冲区大小/可链接数
  12. public static int so_sndbuf=16*1024; // SO_SNDBUF发送缓冲区
  13. public static int so_rcvbuf=16*1024; // SO_RCVBUF接收缓冲区
  14. public static int maxFrameLength=1024; // 每个数据包最大长度
  15. public static int readTimeout=60; // 定义一个定时断线处理器,当多长时间内,没有任何的可读取数据,自动断开连接(单位秒)
  16. public static String CARRIAGE_RETURN="\r\n"; // 结束符
  17. public static boolean loggerDebugger=false;
  18. /**
  19. * 初始化配置文件的参数
  20. */
  21. public static void init(){
  22. Function<String, Integer> function = Integer::parseInt;
  23. // 读配置文件赋值
  24. // port= function.apply(Global.getConfig("port"));
  25. // so_backlog= function.apply(Global.getConfig("so_backlog"));
  26. // so_sndbuf= function.apply(Global.getConfig("so_sndbuf"));
  27. // so_rcvbuf= function.apply(Global.getConfig("so_rcvbuf"));
  28. // maxFrameLength= function.apply(Global.getConfig("maxFrameLength"));
  29. // readTimeout= function.apply(Global.getConfig("readTimeout"));
  30. // CARRIAGE_RETURN= Global.getConfig("CARRIAGE_RETURN");
  31. }
  32. }

NettyConfig类

  1. package com.xiaomage.crm.netty;
  2. import io.netty.channel.Channel;
  3. import io.netty.channel.ChannelId;
  4. import io.netty.channel.group.ChannelGroup;
  5. import io.netty.channel.group.DefaultChannelGroup;
  6. import io.netty.util.concurrent.GlobalEventExecutor;
  7. import org.springframework.util.StringUtils;
  8. import java.util.Map;
  9. import java.util.concurrent.ConcurrentHashMap;
  10. /**
  11. * @version V1.0
  12. * @Title: 存储整个工程的全局配置
  13. */
  14. public class NettyConfig {
  15. /**
  16. * 存储每一个客户端接入进来时的channel对象
  17. */
  18. private static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
  19. public static boolean VcStart = false;
  20. public static String VcContent = "sorry,is close!";
  21. /**
  22. * 认证通道,存储channel和相应客户端编号
  23. * key:设备编号
  24. * val:通道
  25. */
  26. private static Map<String, ChannelId> clientMap = new ConcurrentHashMap<>();
  27. /**
  28. * 未认证的通道
  29. * key:Channel:通道
  30. * val:链接时间
  31. */
  32. private static Map<Integer,Long> temporary_Channel = new ConcurrentHashMap<>();
  33. /**
  34. * 添加临时通道
  35. * 自己的业务处理临时通道目的(将通道与自己的业务信息绑定)
  36. */
  37. public static void addTemporary_Channel(Channel channel){
  38. temporary_Channel.put(channel.id().hashCode(),System.currentTimeMillis());
  39. group.add(channel);
  40. }
  41. /**
  42. * 判断当前通道是否未注册
  43. */
  44. public static boolean ChannelRegister(Channel channel){
  45. return temporary_Channel.containsKey(channel.id().hashCode());
  46. }
  47. /**
  48. * 添加删除临时通道
  49. */
  50. public static void removeTemporary_Channel(Channel channel){
  51. temporary_Channel.remove(channel.id().hashCode());
  52. }
  53. /**
  54. * 保存设备的编号和连接通道的关系
  55. * @param channel
  56. * @param ap
  57. */
  58. public static void addClient(Channel channel,String ap){
  59. //已认证设备清除临时通道
  60. removeTemporary_Channel(channel);
  61. //存储已认证设备
  62. clientMap.put(ap,channel.id());
  63. }
  64. /**
  65. * 获取通道Channel
  66. * @param ap 设备编号
  67. * @return
  68. */
  69. public static Channel getClient(String ap){
  70. ChannelId channelId=clientMap.get(ap);
  71. if(channelId==null)
  72. return null;
  73. Channel Channel=group.find(channelId);
  74. return Channel;
  75. }
  76. /**
  77. * 获取所有通道ChannelAll
  78. * @return
  79. */
  80. public static Map<String, ChannelId> getClientAll(){
  81. return clientMap;
  82. }
  83. /**
  84. * 清除通道
  85. * @param channel 通道Channel
  86. * @return
  87. */
  88. public static void removeClient(Channel channel){
  89. ChannelId cur_channelId=channel.id();
  90. String key=getChannelAp(cur_channelId);
  91. if(!StringUtils.isEmpty(key)){
  92. clientMap.remove(key);
  93. }
  94. group.remove(channel);
  95. }
  96. /**
  97. * 根据通道信息获取设备编号
  98. * @param channelid 通道
  99. * @return
  100. */
  101. public static String getChannelAp(ChannelId channelid){
  102. for (String key : clientMap.keySet()) {
  103. ChannelId channelId=clientMap.get(key);
  104. if(channelid.asLongText().equalsIgnoreCase(channelId.asLongText())){
  105. return key;
  106. }
  107. }
  108. return null;
  109. }
  110. }

3业务类

ExecuteService类

  1. package com.xiaomage.crm.netty;
  2. import com.alibaba.fastjson.JSONObject;
  3. import io.netty.channel.Channel;
  4. import org.springframework.stereotype.Service;
  5. /**
  6. * @version V1.0
  7. * @Title: 业务处理接口
  8. * @Description: //业务处理接口
  9. * @date: 2019/9/24 16:32
  10. */
  11. @Service
  12. public class ExecuteService {
  13. /**
  14. * 当前接受的数据转换为json之后的数据
  15. */
  16. protected JSONObject jsonObject;
  17. /**
  18. * 设备编号
  19. */
  20. protected String deviceID;
  21. /**
  22. * 功能码编号
  23. */
  24. protected String T;
  25. /**
  26. * 本次连接是否合法或者数据是否合法,默认为不合法
  27. */
  28. protected boolean success;
  29. /**
  30. * 相应的业务处理
  31. * @param mes 接收到的数据
  32. * @return
  33. */
  34. public String handler(Channel channel, String mes){
  35. this.success = false;
  36. this.jsonObject = veriData(mes);
  37. if(jsonObject==null){
  38. //解析失败
  39. return ReturnInfo.DownStatePackage(ReturnInfo.ERROR_ANALYSIS);
  40. }
  41. this.T = this.jsonObject.getString("T");
  42. if(!"VV".equals(T)){
  43. if(NettyConfig.ChannelRegister(channel)){
  44. //未注册
  45. return ReturnInfo.DownStatePackage(ReturnInfo.ERROR_REGISTER);
  46. }
  47. }
  48. this.success = true;
  49. return ReturnInfo.DownStatePackage(ReturnInfo.ERROR_UNKNOWN);
  50. }
  51. /**
  52. * 验证接收到的数据是否正确
  53. * @param data 接收到的JSON数据
  54. * @return 返回JSONObject
  55. */
  56. public static JSONObject veriData(String data) {
  57. JSONObject jsonObject=null;
  58. //剔除空的在占位
  59. data=data.trim();
  60. try {
  61. String tempData = data;
  62. jsonObject = ((JSONObject) JSONObject.parse(tempData));
  63. } catch (Exception e) {
  64. System.out.println("convert JSONObject error:"+e.getMessage());
  65. }
  66. return jsonObject;
  67. }
  68. }
  69. ReturnInfo
  70. package com.xiaomage.crm.netty;
  71. import com.alibaba.fastjson.JSONObject;
  72. import io.netty.buffer.Unpooled;
  73. import io.netty.channel.Channel;
  74. import io.netty.channel.ChannelFuture;
  75. import org.slf4j.Logger;
  76. import org.slf4j.LoggerFactory;
  77. import java.io.UnsupportedEncodingException;
  78. import java.util.LinkedHashMap;
  79. /**
  80. * @version V1.0
  81. * @Title: 返回信息控制类
  82. * @Description: //返回信息,以及描述返回状态码的信息
  83. * @date: 2019/9/24 17:57
  84. */
  85. public class ReturnInfo {
  86. /**
  87. * 解析失败
  88. */
  89. public static final int ERROR_ANALYSIS=0;
  90. /**
  91. * 接收成功
  92. */
  93. public static final int sussecs=1;
  94. /**
  95. * 接收成功,有反馈数据(只有一条)
  96. */
  97. public static final int sussecs2=2;
  98. /**
  99. * 接收成功,有反馈数据(多条)
  100. */
  101. public static final int sussecs3=3;
  102. /**
  103. * 未知异常
  104. */
  105. public static final int ERROR_UNKNOWN=-1;
  106. /**
  107. * 超时未通信
  108. */
  109. public static final int ERROR_OVERTIME=-2;
  110. /**
  111. * T不存在(T表示功能编号,例如V1、V2)
  112. */
  113. public static final int ERROR_T_IS_NOT_FOUND=-3;
  114. /**
  115. * 未注册
  116. */
  117. public static final int ERROR_REGISTER=-4;
  118. /**
  119. * L数据出错
  120. */
  121. public static final int ERROR_L=-5;
  122. /**
  123. * 查询固件不存在
  124. */
  125. public static final int ERROR_PACKAGE=-6;
  126. /**
  127. * 命令数据转换json对象失败
  128. */
  129. public static final int ERROR_CONVERTJSON=-7;
  130. // 日志
  131. protected static Logger logger = LoggerFactory.getLogger(ReturnInfo.class);
  132. /**
  133. * 下行-结果包
  134. * @param t 0:json解析失败 1:接收成功(且无数据下发,表心跳) -4:通道未注册 -1:未知异常
  135. * @return String 封装的结果内容
  136. */
  137. public static String DownStatePackage(int t){
  138. LinkedHashMap linkHashMap = new LinkedHashMap();
  139. linkHashMap.put("S", t);
  140. JSONObject jsonObject = new JSONObject(linkHashMap);
  141. String resultInfo = jsonObject.toJSONString();
  142. return resultInfo;
  143. }
  144. /**
  145. * 指定通道下发数据
  146. * @param channel 通道
  147. * @param msg 发送消息内容
  148. */
  149. public static ChannelFuture sendMsg(Channel channel, String msg){
  150. //判断是否需要日志
  151. if (NettyProperties.loggerDebugger) {
  152. logger.info("sendMsg:"+ msg);
  153. }
  154. //统一添加结束符
  155. msg = msg + NettyProperties.CARRIAGE_RETURN;
  156. //发送并返回
  157. return channel.writeAndFlush(Unpooled.copiedBuffer(getBytesStr(msg)));
  158. }
  159. /**
  160. * 转换字符串为byte[]
  161. * @param str 要发送的字符串内容
  162. * @return byte[] 子节数组,异常返回null
  163. */
  164. private static byte[] getBytesStr(String str){
  165. try {
  166. return str.getBytes("UTF-8");
  167. } catch (UnsupportedEncodingException e) {
  168. logger.error("getBytesStr error:"+e.getMessage());
  169. }
  170. return null;
  171. }
  172. }

其它业务类

  1. package com.xiaomage.crm.netty;
  2. import com.alibaba.fastjson.JSONObject;
  3. import io.netty.channel.Channel;
  4. import org.springframework.stereotype.Service;
  5. /**
  6. * @version V1.0
  7. * @Title: 通道注册 业务类
  8. * @Description: //上行--通道注册
  9. * @date: 2019/9/24 16:34
  10. */
  11. @Service
  12. public class VV extends ExecuteService{
  13. @Override
  14. public String handler(Channel channel, String mes) {
  15. String superres=super.handler(channel,mes);
  16. if(!this.success)
  17. return superres;
  18. JSONObject jsonObject=this.jsonObject;
  19. this.deviceID=jsonObject.get("U").toString();
  20. // //添加通道并注册
  21. NettyConfig.addClient(channel,deviceID);
  22. return ReturnInfo.DownStatePackage(ReturnInfo.sussecs);
  23. }
  24. }

与spring集成获取spring中bean的工具类

  1. package com.xiaomage.crm.taskQueue;
  2. import org.springframework.beans.BeansException;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.ApplicationContextAware;
  5. import org.springframework.lang.Nullable;
  6. import org.springframework.stereotype.Component;
  7. /**
  8. * 获取spring的bean
  9. */
  10. @Component
  11. public class SpringContextUtil implements ApplicationContextAware {
  12. private static ApplicationContext applicationContext = null;
  13. @Override
  14. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  15. if (SpringContextUtil.applicationContext == null) {
  16. SpringContextUtil.applicationContext = applicationContext;
  17. //System.out.println( "========ApplicationContext配置成功,在普通类可以通过调用ToolSpring.getAppContext()获取applicationContext对象,applicationContext="+ applicationContext + "========");
  18. }
  19. }
  20. public static ApplicationContext getApplicationContext() {
  21. return applicationContext;
  22. }
  23. public static Object getBean(String name) {
  24. return getApplicationContext().getBean(name);
  25. }
  26. public static <T>T getBean(Class<T> clazz) {
  27. // TODO Auto-generated method stub
  28. return getApplicationContext().getBean(clazz);
  29. }
  30. public static <T> T getBean(String var1, @Nullable Class<T> var2){
  31. return applicationContext.getBean(var1, var2);
  32. }
  33. }

发表评论

表情:
评论列表 (有 0 条评论,449人围观)

还没有评论,来说两句吧...

相关阅读

    相关 pandas 使用

    这周在做一个平台测试的活,东西不难,开发加上测试原本打算两天搞定,结果直接干到了周五下午才交了活。中间的“曲折”过程就不一一赘述了,有个很深的感悟是:设计真的很重要!开发的最终

    相关 面试

        2019.7.16日  天气:暴热暴晒,撑着伞都顶不住...   今天去面试前端实习生,到公司后就直接开始写笔试题目,然后写完后,与面试官进行交谈,发现自己的一些不足,

    相关 netty使用

    前言:笔者在项目中使用的netty的场景是这样的,(物联网公司)所有机柜使用长连接连接到服务器,而服务器使用的正好是netty,所以不得已笔者需要学习netty的一些知识,这里