tomcat下的struts2+CDI(weld)+JPA配置

之前一直用JavaEE的服务器软件,CDI,JPA都是默认支持的,配置方面很简单。最近在学习axon和axon-cdi(CDI api 1.1),想使用轻量一点的应用服务器,选择了tomcat,配置方面总是有些问题,不过终于可以跑了,记录一下。

1.首先,使用基本的tomcat 7,而不是TomEE,TomeEE不支持cdi-api 1.1

2.使用weld作为cdi的实现,它可以在j2se下运行,所以可以整合到tomcat中去。

3.用到了struts2,也需要一点配置才能使用cdi模块

maven工程,

首先,在pom.xml中增加cdi和weld的依赖:

<dependency>
	<groupId>org.jboss.weld.servlet</groupId>
	<artifactId>weld-servlet-core</artifactId>
	<version>2.3.3.Final</version>
</dependency>

然后在WEB-INF/下增加beans.xml文件,在WEB-INF/web.xml中增加weld监听器,使这个web应用可以使用weld的CDI:

<listener>
    <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
  </listener>

这样在普通的java类中就可以使用基本的CDI了。到这里都很简单。

第二步,配置struts2的cdi支持。增加struts2的cdi支持,增加依赖:

<dependency>
       	<groupId>org.apache.struts</groupId>
       	<artifactId>struts2-cdi-plugin</artifactId>
       	<version>2.3.20</version>
       </dependency>

在web.xml中增加strtus2的filter配置:

<filter>
  		<filter-name>struts2</filter-name>
	  	<filter-class>
	  		org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
	  	</filter-class>
	  	<init-param>
			<param-name>loggerFactory</param-name>
			<param-value>
				com.opensymphony.xwork2.util.logging.commons.CommonsLoggerFactory
			</param-value>
		</init-param>
	 </filter>
  <filter-mapping>
  	<filter-name>struts2</filter-name>
  	<url-pattern>*.action</url-pattern>
  </filter-mapping>


按说,到这一步,部署后就可以直接使用strtus2的CDI了,但是实际上遇到了一个情况,就是启动tomcat时strtus2通过jndi查找BeanManager失败了。通过查找jboss上的文档,可以用如下方式配置:

1.在web根目录下的META-INF中,建立一个context.xml文件,文件配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <!-- disables storage of sessions across restarts -->
  <!-- <Manager pathname=""/> -->
 
  <Resource name="BeanManager"
            auth="Container"
            type="javax.enterprise.inject.spi.BeanManager"
            factory="org.jboss.weld.resources.ManagerObjectFactory"/>
            
 	<Resource name="jdbc/axon" auth="Container" type="javax.sql.DataSource"  
        maxActive="20" maxIdel="10" maxWait="1000" username="root"  
        password="1234" driverClassName="com.mysql.jdbc.Driver"  
        url="jdbc:mysql://localhost:3306/axon?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8">  
    </Resource> 
  <!-- enable injection into Servlet -->
  <!-- <Listener className="org.jboss.weld.environment.tomcat.WeldLifecycleListener"/> -->
 
  <!--
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <WatchedResource>META-INF/context.xml</WatchedResource>
  -->
</Context>

以上内容,name="BeanManager"的是beanManager的jndi配置(还有个数据源的配置,下面也用的着),然后在应用的web.xml中增加资源配置:

 <resource-env-ref>
    <description>Object factory for the CDI Bean Manager</description>
    <resource-env-ref-name>BeanManager</resource-env-ref-name>
    <resource-env-ref-type>
      javax.enterprise.inject.spi.BeanManager
    </resource-env-ref-type>
  </resource-env-ref>
  <resource-ref>
    <description>MySQL DBCP</description>
    <res-ref-name>jdbc/axon</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

有了以上配置,struts2就可以通过java:comp/env/BeanManager找到CDI的BeanManager了。同样,以上也包含了mysql的数据源的资源配置,同上面的context.xml中的内容相对应。

下面就是配置JPA了,META-INF/persistence.xml如下(不是webroot下的META-INF,是类路径下的,如在源代码的src/下):

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">	
    <persistence-unit name="addresses" transaction-type="RESOURCE_LOCAL">
    	<non-jta-data-source>java:comp/env/jdbc/axon</non-jta-data-source>
    
    	
       
        <class>com.ngworld.dddproj.domain.model.query.AddressEntry</class>
        <class>com.ngworld.dddproj.domain.model.query.ContactEntry</class>
        <class>com.ngworld.dddproj.domain.model.command.ClaimedContactName</class>

        <class>org.axonframework.eventstore.jpa.DomainEventEntry</class>
        <class>org.axonframework.eventstore.jpa.SnapshotEventEntry</class>
        <properties>
            <property name="hibernate.archive.autodetection" value="class"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
         	<property name="hibernate.hbm2ddl.auto" value="validate" />
         	<property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>
</persistence>
注意,tomcat不是EE容器,只能使用transaction-type只能是RESOURCE_LOCAL,而且不能使用jta-data-source,而是non-jta-data-source。

,在pom.xml中增加hibernate和其jpa实现的依赖:、

<dependency>
        	<groupId>org.hibernate</groupId>
        	<artifactId>hibernate-entitymanager</artifactId>
        	<version>5.1.0.Final</version>
		</dependency>


这样文件方面就配置完成了,需要编写JPA中EntityManager的producer了:

package com.ngworld.dddproj.axonintegration;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;

@ApplicationScoped
public class EntityManagerProducer {
	//@PersistenceContext//(unitName = "addresses")//non EE server use it
	//private EntityManager entityManager;
	//@PersistenceUnit(unitName="addresses") //EE server use this
    //private EntityManagerFactory entityManagerFactory;
	private static final EntityManagerFactory factory =  Persistence.createEntityManagerFactory("addresses"); 
	
	@Produces
    @Default
    @RequestScoped
    public EntityManager create()
    {
		return factory.createEntityManager();
		//return entityManager;
        //return this.entityManagerFactory.createEntityManager();
    }

    public void dispose(@Disposes @Default EntityManager entityManager)
    {
        if (entityManager.isOpen())
        {
            entityManager.close();
        }
    }
}

@PersistenceContext和@PersistenceUnit这两种注解都没有效果,只能手动初始化entitymanager:EntityManagerFactory factory =  Persistence.createEntityManagerFactory("addresses"); 


这样基本上就完成了,在使用entitymanager的地方,直接使用@Inject就可以了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值