Netty网络聊天室之使用spring管理各种组件

原创 2017年08月10日 21:04:16
Spring是web开发的宠儿,不管mvc框架选择structs还是SpringMVC,IOC容器都是选择Spring。Spring有两个主要的作用,一个是IOC(依赖注入),另一个是AOP(面向切面编程)。只要是java项目,就可以使用这个框架。
在这里,我不过多对Spring进行布道。说一下有没有使用Spring的编码习惯。若不采用Spring进行项目开发,我们每个类一般都是采用单例的模式,例如 UserService.getInstance();使用了Spring,就只需要在UserService加个注解就可以把它丢入spring容器(Spring默认创建对象就是使用单例模式)。如果其他模块需要调用UserService的接口,只需要从spring容器把它拿出来即可,非常方便。

对于没有接触Spring的童鞋,只需要知道Spring是一个巨大的对象容器。使用@Component,@Servoce,@Controller,@Repository可以把对象放入容器,使用@Resource,@Autowired可以从容器里取对象。

spring管理组件的配置方式

1. 项目里受spring管理的组件是非常多的,所以我们需要能让spring容器自动扫描所有组件,只需要在spring配置加上这一行就可以了

<context:component-scan base-package="com.kingston" />
2. 把组件交给spring容器管理,配置如下

@Repository
public interface UserDao 
3. 使用Spring容器里的对象,配置如下

@Component
public class LoginService {

	@Autowired
	private UserDao userDao;
}

需要特别注意的是,这里用Autowired注解从spring里拿对象,LoginService本身也必须受spring管理,否则就需要手动从spring获取bean。

缓存Spring容器本身引用

1. 不是所有对象都放在spring容器里的。若某个对象本身没有放入spring里,想要拿spring容器的组件,就只能从spring的容器上下文环境中获取。所以,有必要把这个spring容器上下文缓存起来。要获取spring容器,只需要类实现ApplicationContextAware这个接口即可。像这样

public class SpringContext implements ApplicationContextAware {
	/** spring容器上下文 */
	private static ApplicationContext applicationContext = null;
	/** 异步持久化服务 */
	private static AysncDbService aysncDbService;
	
	private static ChatService chatService;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		SpringContext.applicationContext = applicationContext;
	}
	
	public final static <T> T getBean(Class<T> clazz) {
		return applicationContext.getBean(clazz);
	}
	
	public final static <T> Collection<T> getBeansOfType(Class<T> clazz) {
		return applicationContext.getBeansOfType(clazz).values();
	}
	
	public final static <T> T getBean(String name, Class<T> requiredType) {
		return applicationContext.getBean(name, requiredType);
	}

	@Resource
	public void setAysncDbService(AysncDbService aysncDbService) {
		SpringContext.aysncDbService = aysncDbService;
	}
	
	public static AysncDbService getAysncDbService() {
		return aysncDbService;
	}
	
	@Resource
	public void setChatService(ChatService chatService) {
		SpringContext.chatService = chatService;
	}
	
	public final static ChatService getChatService() {
		return chatService;
	}
	
}
并把SpringContext配置成spring的组件

	<!-- 注册spring上下文环境 -->
	<bean id="context" class="com.kingston.base.SpringContext" />
2. 非spring管理的实例想要获取spring组件,就可以像这样子了
	AbstractPacket  packet = (AbstractPacket)msg;
	System.err.println("receive pact, content is " + packet.getClass().getSimpleName());
	if(packet.getPacketType() == PacketType.ReqUserLogin ){
		ReqUserLoginPacket loginPact = (ReqUserLoginPacket)packet;
		
		LoginService loginMgr = SpringContext.getBean(LoginService.class);
		loginMgr.validateLogin(context,loginPact.getUserId(), loginPact.getUserPwd());
		return ;
	}

spring与mybatics的结合

使用了spring之后,数据库连接的数据源,以及Mybatics的SqlSessionFactoryBean就统统在spring进行配置就可以了。

1. 使用mybatis-spring库(mybatics整合spring的工具库),可以直接让spring扫描所有mybatics的mapper配置

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation" value="config/mybatis-config.xml" />
		<!-- 自动扫描所有mapper配置 -->
		<property name="mapperLocations"
			value="classpath:com/kingston/data/mybatis/*Mapper.xml" />
	</bean>
2. 使用mybatis-spring库,可以自动扫描所有dao并注入到spring容器
	<!-- 自动扫描所有dao并注入到spring容器 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.kingston.data.dao" />
	</bean>

3. 这样一来,mybatics本身的配置就变得可有可无啦。不过,一些组件的别名申明还是可以放到mybatics的配置里

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!--别名申明 -->
	<typeAliases>
		<typeAlias type="com.kingston.data.model.User" alias="user" />
	</typeAliases>
	
</configuration>
UserMapper.xml配置里的 resultType="user" ,这里的 "user"就指向上面的完整类路径
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kingston.data.dao.UserDao">
	<select id="findById" parameterType="java.lang.Long"
		resultType="user">
		select * from user where userId=#{userId}
	</select>
	<insert id="addUser" parameterType="user">
		insert into user(userId,userName,authentication) 
			values(#{userId},#{userName},#{authentication})
	</insert>
	<update id="updateUser" parameterType="user">
		update user
		set
		userName=#{userName}
		where userId=#{userId}
	</update>
	<delete id="delUser" parameterType="java.lang.Long">
		delete from user
		where
		userId=#{userId}
	</delete>
</mapper>

Spring结合Groovy脚本实现热部署

Groovy是JVM上的一门脚本语言,当Spring遇上了Groovy,就会缔造完美的效果。当部分spring组件需要在程序运行过程中实现代码热部署,只需要用Groovy的类加载器加载。具体的操作可以看下点击打开链接 这篇文章。
在实际使用环境,我们把需要热更新的代码统一放到src/groovy目录下。需要注意的是,ides开发环境跟jar包生产环境获取groovy目录的spring组件的方式是不同的。
在ide环境,只要将src/groovy目录标记为代码根目录,spring容器启动的时候,就可以扫描到groovy目录下被spring注解标记的组件。
在生产环境,我们使用maven作为打包工具,但maven 默认只把src/main目录下的java文件编译到目标jar包,我们自定义的src/groovy目录是不会打进包里的。这样更好,因为我们本来就不希望我们的groovy目录被编译成class。
我们希望groovy的目录与jar包分离,并且以源码的形式存在。当需要更新groovy里某个文件的代码时,直接替换文件即可。GroovyFactory类在扫描的时候,只要把扫描的根目录指向跟jar包同一目录下的groovy,也可以拿到groovy的spring组件。


全部代码已在github上托管

服务端代码请移步 --> netty聊天室服务器

客户端代码请移步 --> netty聊天室客户端





版权声明:本文为博主原创文章,未经博主允许不得转载。

Netty网络聊天室之会话管理

浏览器第一次与服务器建立连接的时候,服务器就会自动为之分配一个Session。在我们的聊天室,也可以使用Session来判断用户是否经过登录验证,保存用户的各种信息,向客户端发送消息。这极大方便了程序...

手游服务端框架之使用Guava构建缓存系统

缓存,在项目中的应用非常之广泛。诸如这样的场景,某些对象计算或者获取的代码比较昂贵,并且在程序里你不止一次要用到这些对象,那么,你就应该使用缓存。缓存,在项目中的应用非常之广泛。诸如这样的场景,某些对...

Spring Boot实战之netty-socketio实现简单聊天室(给指定用户推送消息)

Spring Boot实战之netty-socketio实现简单聊天室(给指定用户推送消息) 网上好多例子都是群发的,本文实现一对一的发送,给指定客户端进行消息推送 1、本文使用到...
  • sun_t89
  • sun_t89
  • 2016年07月29日 07:56
  • 17188

Netty网络聊天室之基础网关搭建

基本Netty通信框架开发一个模仿QQ的聊天室。使用Netty作为通信网关,使用JavaFX开发客户端界面,使用Spring作为IOC容器,使用MyBatics支持持久化。本文将着重介绍服务端客户端框...

Netty网络聊天室之心跳检测及断线重连

为了适应恶劣的网络环境,比如网络超时、闪断,客户端进程僵死,Netty需要机制来保证双方的通信能正常工作或者自动恢复。对于服务端来说,当客户端由于某些原因导致无法与服务端通信的,服务端需要主动注销与客...

Spring Boot实战之netty-socketio实现简单聊天室(给指定用户推送消息)

spring Boot实战之netty-socketio实现简单聊天室(给指定用户推送消息) 网上好多例子都是群发的,本文实现一对一的发送,给指定客户端进行消息推送 1、本文使用到...

基于netty的网络聊天室(二)——心跳检测及断线重连

前面介绍了Netty服务端客户端基本通信框架的搭建过程。下面将介绍Netty如何进行心跳检测以及处理客户端的断线重连。 为了适应恶劣的网络环境,比如网络超时、闪断,客户端进程僵死,需要机制来保证双方...
  • joeyon
  • joeyon
  • 2016年12月01日 17:06
  • 277

java_OA管理系统(一):Servlet总结案例仿网络聊天室

因为我们学校的软件联盟要为我们校区开发一个OA系统,为此我将其所需要的一些技术进行汇总,以便web组组员开发所用. 第一篇是关于Servlet的一个汇总案例,算是开个简单的小头. 一.总述 代码来源于...

使用Android网络编程实现简易聊天室

http://blog.csdn.net/u010142437/article/details/9327541 在Java中我们可以利用socket编程实现聊天室,在Android中也一样,因为...

linux socket实现网络聊天室(二):使用线程独立收发消息

一、引言 二、代码实现 1、服务器端 /*tcpserver.c 2011.9.1 by yyg*/ #include #include #include #include ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Netty网络聊天室之使用spring管理各种组件
举报原因:
原因补充:

(最多只允许输入30个字)