maven
tomcat-jdbc hibernate 版本冲突
搭建了一套 Spring 核心的 web 服务基础框架。
涉及 Spring 4.2.1.RELEASE , Spring MVC 4.2.1.RELEASE ,Spring Data JPA 1.9.0.RELEASE, Hibernate 5.0.2.Final, 数据库连接池 tomcat-jdbc 8.27, 容器 tomcat 8.21。
坑人的异常:
1 | org.apache.tomcat.jdbc.pool.ConnectionPool abandon |
奇怪的异常, 折腾半天,把 tomcat-jdbc 的配置属性玩了个遍,没辙, 想起以前版本没问题, Hibernate 5.0.2.Final 降级成 Hibernate 4.3.11.Final;
然后就好了!!!!!!
似乎是 对 Hibernate 5 的支持还不够广泛。
ps 推荐一个 tomcat 8 中文文档, 翻译的还可以。
questions
对象的引用 reference
很多现代语言都有 GC
,与 GC
紧密相关的是对象的引用。
Java
Java有4种引用类型:
强引用 StrongReference: 平常使用的都是这种,其他引用统称
弱引用
。强引用可以直接访问目标对象。
强引用所指向的对象在任何时候都不会被系统回收。
强引用可能导致内存泄漏。
1 | Bean bean = new Bean(); |
软引用 SoftReference: 最强的弱引用, 内存紧缺时可能会被GC回收。
软引用使用 get() 方法取得对象的强引用从而访问目标对象。
软引用所指向的对象按照 JVM 的使用情况(Heap 内存是否临近阈值)来决定是否回收。
软引用可以避免 Heap 内存不足所导致的异常。
1 | SoftReference<Bean> bean = new SoftReference<Bean>(new Bean()); |
弱引用 WeakReference :
弱引用使用 get() 方法取得对象的强引用从而访问目标对象。
一旦系统内存回收,无论内存是否紧张,弱引用指向的对象都会被回收。
弱引用也可以避免 Heap 内存不足所导致的异常。
1 | WeakReference<Bean> bean = new WeakReference<Bean>(new Bean()); |
- 虚引用 PhantomReference: 始终是null
1 | ReferenceQueue<Bean> refQueue = new ReferenceQueue<Bean>(); |
有篇可以参照 blog
Swift
Swift 使用自动引用计数(ARC)机制来跟踪和管理你的应用程序的内存。
Swift有3种引用类型:
- 强引用 StrongReference: ARC + 1,ARC 不会销毁被引用的实例
1 | class Person { |
- 弱引用 WeakReference : 弱引用不会对其引用的实例保持强引用,因而不会阻止 ARC 销毁被引用的实例。
1 | class Apartment { |
无主引用 unowned : 无主引用是永远有值的。总是被定义为非可选类型(non-optional type)。总是可以被直接访问。
1
2
3
4
5
6
7class Customer {
var card: CreditCard?
}
class CreditCard {
unowned let customer: Customer
}无主引用以及隐式解析可选属性
1
2
3
4
5
6
7class Country {
var capitalCity: City!
}
class City {
unowned let country: Country
}
Person和Apartment的例子展示了两个属性的值都允许为nil,并会潜在的产生循环强引用。这种场景最适合用弱引用来解决。
Customer和CreditCard的例子展示了一个属性的值允许为nil,而另一个属性的值不允许为nil,这也可能会产生循环强引用。这种场景最适合通过无主引用来解决。
Country和City的例子中两个属性都必须有值,并且初始化完成后永远不会为nil。在这种场景中,需要一个类使用无主属性,而另外一个类使用隐式解析可选属性。
更详细的内容可以参考 中译 Swift
nexus 不能自动下载 restlet jars 的解决方案
今天用到了 activiti 5.16;它依赖 org.restlet.jee:org.restlet:2.2.1
等 jar。奇怪的事情发现了, 一向运行良好的 nexus 出问题,org.restlet.jee:org.restletxxx:2.2.1
一系列的jars都无法下载。这里吐草下,org.restlet.jee:org.restletxxx
看着就别扭,so nexus 也找不到它,自然也无法下载。
解决方案如下:
增加restlet的Repository
管理员账户登录nexus 控制台, 增加restlet的Repository,类型为proxy
具体内容参照下图,重要Remote Storage Location
设置为http://maven.restlet.com/
restlet 加入 Public repositories group
清除本地 Repositories
别忘了删除 maven 的本地 repositories 里的 restlet 文件夹。
activemq(三) Spring集成 - 消息驱动
上篇介绍了 集成Spring-远程调用, 本次介绍集成 Spring, 常规JMS,消息驱动。主角是 activeMq, JmsTemplate, @JmsListener。
- activeMq 是消息总线,JMS provider;
- JmsTemplate 是由 Spring提供的消息模板,简化消息生产者和消费者端的代码开发量。就是封装了 连接JMS provider(如ActiveMQ),建立JMS Session(如QueueSession),建立消息生产者,建立消费者,发送消息,接收消息;
- @JmsListener 由 Spring 提供的最简单的消息接收端操作方式。
准备
必须的jar
maven管理的方式
1 | <dependency> |
activemq 的 PooledConnectionFactory 会调用 commons-pool2。
PropertySourcesPlaceholderConfigurer
配置PropertySourcesPlaceholderConfigurer
, 下面用得着,比较优雅。
1 | @Configuration |
配置
消息生产者和消费者都需要。
1 | import org.apache.activemq.ActiveMQConnectionFactory; |
补充说明:
- @EnableJms:开启 JMS 注解, 这样 @JmsListener 等注解才会生效;默认需要jmsListenerContainerFactory 这个 Bean。
- activeMq PooledConnectionFactory 和 springCachingConnectionFactory 同等作用,可以替换。
- testQueue 具体value 在 jms.properties 里配置,类似常量。
消息发送和接收
首先看代码
1 | @Service("GmGameAchvServiceImpl") |
- 消息发送
方法jmsSendTest
, 利用 jmsTemplate 很方便 - 消息接收
JmsReceiveTest
, 使用了@JmsListener
,这是最简单的方式,比 jmsTemplate 更简单。@JmsListener
需要制定destination
, 这里${testQueue}
的值由conf/jms.properties
里具体制定, 由上文提到的PropertySourcesPlaceholderConfigurer
负责转化。 如此在一个配置文件里配置,多个地方使用,如需改动,仅需修改配置文件,不用修改源代码。
消息数据转换 Message Converters
Spring 会自动进行消息转换, 比如上面 jmsSendTest
发送的是 TextMessage
, JmsReceiveTest
用 String 类型参数接收就好。POJO 对象一样可以如此操作。
1 | @Override |
如此这般就好了,是不是 很简单方便。
响应管理
1 | @JmsListener(destination = "myQueue") |
@SendTo
就可以返回值 到 queueOut
这个destination
~~~~~~~ 嗯嗯, 很不错的样子 :)
activemq集合贴
activemq (二) 集成Spring-远程调用
上篇介绍了 activemq 的安装和使用,这篇介绍下集成 spring 最简单的运用,远程调用。注意,这种方式是没有事务控制的。
加入activemq 的 jar
maven 方式
1 | <dependency> |
辅助类
接口(服务端和客户端都要有)
1
2
3
4
5
6
7
8
9public interface IGmGameAchvService
{
/**
* 根据ID获取对象
* @param companyId
* @return
*/
GmGameAchvEntity findById(Long id);
}实现(服务端)
1
2
3
4
5
6
7
8
9
10
11
12@Service("GmGameAchvServiceImpl")
public class GmGameAchvServiceImpl implements IGmGameAchvService
{
@Override
public GmGameAchvEntity findById(Long id)
{
GmGameAchvEntity achv = new GmGameAchvEntity();
achv.setId(1L);
return achv;
}
}
配置
概要
如下内容服务端和客户端都需要配置
1 jmsConnectionFactory
2 jmsQueue
服务端另需配置
3 MessageListenerContainer
4 ServiceExporter
客户端另需配置
5 ProxyFactoryBean
具体内容
以下都是java based的配置,xml的配置可以参考 Spring doc
- jmsConnectionFactory jmsQueue
1 | @Configuration |
服务端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35@Configuration
public class JmsServerConfiguration
{
@Autowired
private IGmGameAchvService gameAchvService;
@Autowired
private ActiveMQConnectionFactory jmsConnectionFactory;
@Autowired
private ActiveMQQueue jmsQueue;
@Bean
public JmsInvokerServiceExporter service()
{
JmsInvokerServiceExporter service = new JmsInvokerServiceExporter();
service.setServiceInterface(IGmGameAchvService.class);
service.setService(gameAchvService);
return service;
}
@Bean
public SimpleMessageListenerContainer msgListenerContainer()
{
SimpleMessageListenerContainer msgListenerContainer = new SimpleMessageListenerContainer();
msgListenerContainer.setConnectionFactory(jmsConnectionFactory);
msgListenerContainer.setDestination(jmsQueue);
msgListenerContainer.setConcurrentConsumers(3);
msgListenerContainer.setMessageListener(service());
return msgListenerContainer;
}
}客户端
配置1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20@Configuration
public class JmsClientConfiguration
{
@Autowired
private ActiveMQConnectionFactory jmsConnectionFactory;
@Autowired
private ActiveMQQueue jmsQueue;
@Bean
public JmsInvokerProxyFactoryBean achvService()
{
JmsInvokerProxyFactoryBean service = new JmsInvokerProxyFactoryBean();
service.setServiceInterface(IGmGameAchvService.class);
service.setConnectionFactory(jmsConnectionFactory);
service.setQueue(jmsQueue);
return service;
}
}
调用
1 | IGmGameAchvService gmservice = (IGmGameAchvService) service; |
监控
正常启动后, 在 activemq 的监控中可以看到相应内容。
如
Queues
connections
activemq集合贴
web 服务器
整理一些常用的服务器知识,配置和使用实例。这里仅作简单介绍。
陆续更新。。。
tomcat
使用最广泛的 Web 应用服务器和 servlet 容器,不多说了。tomEE(发音同“tommy”)
完全兼容tomcat,从名字看就知道和tomcat关系密切。TomEE仅仅是Tomcat的一个扩展版本,任何能在Tomcat上使用的工具,如像Eclipse WTP一样的IDE工具,全部都能用在TomEE上。 TomEE=Tomcat+java EE,TomEE嵌入了EJB、CDI和其他JavaEE特征到Tomcat里,是一个完整符合Web Profile的服务器。[nginx](/2016/01/22/web server/nginx/nginx/)
是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 服务器。基本用的是前面的功能 :)wildfly(Jboss as)
JBoss Application Server(JBoss AS) 改名成 wildfly, 版本升级真快。提供完整的Java EE 栈。开源免费。jetty
开源的servlet容器