一,概要
回顾去年工作中遇到的问题与解决方案,总结新的技术成果
二,问题回顾
1,在mybatis 映射配置文件中,存在A , B 两张外键约束关联表,若字段相同则结果映射会出现级联查询时映射结果赋值错误问题,解决方案,一般在配置文件中对数据库字段进行as映射,或者主外键关系的字段与属性映射配置中配置select属性例如
2,在dubbo 2.5.4以前的版本框架中存在其自身assecc-log组件bug,若在dubbo服务消费者个提供者配置assess_log属性,则控制台会抛出严重的内存溢出错误,原因是dubbo的rpc调用时,对json的对象的传输有一定程度上的缺陷,会出现递归调用,导致控制台输出错误的堆栈信息警告
3,redis的使用需要注意对其分配的内存大小,单机版不足以胜任其性能要求时,必须进行集群搭建,做主从配置,防止内存溢出错误与数据丢失,产生数据混乱
4,java本身的mail支持需要第三方邮件服务器对外提供smtp服务与pop3服务
5,服务器针对多种环境的配置,需要进行优化(如现有的通过同一路径的不同文件夹中的配置文件,进行区别)
6 ,java的国际化实现
1.在spring-bean.xml的配置文件中配置<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames"><list>
<value>classpath:com/hlink/i18n/resource</value>
<!--此处的路径为:resource_en_US.properties 为名称的国际化配置文件-->
</list></property>
<!--① 刷新资源文件的周期,以秒为单位 -->
<property name="cacheSeconds" value="7200" />
</bean> 节点,
2.在需要用到的国际化配置的地方注入MessageSource messageSource;
3.在“resource_语言_国别.properties“的国际化配置文件中配置对应key=value 键值对,例如:REQUEST_PARAMS_ERR=Request parameter exception,此处注意不同的配置文件中的所有key永远是相同的,value是不同语言体系下的各种各种同一表意的译句,
4.在需要用到国际化的地方使用 : messageSource.getMessage("需要的译句的key", null, locale));
7WebApplicationContex wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());加载项目中servlet配置, wac.getBean("spring-bean.xml中bean节点的id值");获取spring管理的bean对象,InputStream inputStream=ActivemqBrokerListener.class.getClassLoader().getResourceAsStream("key=value格式的参数配置文件.properties");获取使用属性文件配置的参数群对象,使用Properties p = new Properties();
p.load(inputStream);
参数value = p.getProperty("参数key");
8,amq插件开发
1.找齐jar包,activemq-core activemq-all 以及derby jetty相关包
2.项目结构
3.使用ServletContextListener监听器负责启动加载插件,contextInitialized()方法进行属性文件的加载以及插件的初始化,为了多环境运行,插件的初始化参数有参数配置文件进行配置,不得写死,contextDestroyed()方法负责销毁插件并释放资源
4.插件中的参数传递
5.插件的工作原理既是对mqtt协议通信连接的个阶段的处理:
当添加链接时addConnection(ConnectionContext context, ConnectionInfo info) ;
当生成会话时addSession(ConnectionContext context, SessionInfo info);
当添加消息推送主题时addProducer(ConnectionContext context, ProducerInfo info);
当添加订阅主题时addConsumer(ConnectionContext context, ConsumerInfo info);
客户端断开时removeConnection(ConnectionContext context, ConnectionInfo info, Throwable error);
当插件接收到客户端消息时send(ProducerBrokerExchange producerExchange, Message messageSend);
当取消订阅时removeConsumer(ConnectionContext context, ConsumerInfo info);
程序员需要做的就是根据自己的业务需要在以上的各种不同的阶段进行,自己的逻辑编码,完成自己的功能需求
9,定时器操作
1.常用的定时器有很多,其中以jdk类库自带的TimerTask与Timer,spring-Quartz 最为常见,Quartz的使用异常简单
在需要定时运行的executeJob()方法上使用@Scheduled(cron = "59 59 23 * * ?")注解,在spring-bean.xml配置<task:annotation-driven />定时任务扫描即可开启定时任务。要求方法名必须是executeJob(),必须有@Scheduled注解,必须开启定时任务的扫描
注意cron表达式的含义是程序没到这个时间就会运行,其关注的是时间运行的时间点,而Timer则侧重于间隔时间,例如
其意思为,第一次运行在程序执行的60秒后,之后每隔60秒执行一次
10,系统架构方面,使用amq队列,对消息进行异步处理,保证服务器对请求的高效处理
11,数据加密,签名,使用不同的算法规则对数据串进行加密运算,必须保证解密的secret是唯一的并是有时效性的
12,数据库的升级迭代,需要兼容旧版本的各项功能,不得影响,或改变原有的功能模块,只允许扩展,