OSGI下的web应用开发(6)

这一节进入Service Interface Bundle和Service Implementation Bundle的开发。

同样的,首先先来看看类图



 
 为了简化对service的操作,一样定义了一个基础服务接口。

  • Service Interface Bundle

(1)新建Bundle Project项目

当项目创建完后,我们需要先把项目间的关联关系设定好再开始编码。如图



 勾选上dao2和domain两个项目,因为我们会引用到这两个项目的类。

(2)代码

(2.1) IBaseService

package net.georgezeng.test.service;

import java.util.List;

public interface IBaseService<T> {
  void save(T t);
  T get(Long id);
  List<T> findList(T t);
}
 

(2.2)ContactService

package net.georgezeng.test.service;

import net.georgezeng.test.domain.Contact;

public interface ContactService extends IBaseService<Contact> {
  
}
 

(3)MANIFEST.MF的定义

(3.1)import


(3.2)export


这样Service Interface Bundle就开发完成了

  • Service Implementation Bundle
(1)创建Bundle Project项目
同样的,创建完后需要关联相关的项目。如图


 引入了3个关联的项目,分别是dao2,domain和service

(2)代码

(2.1)BaseService

package net.georgezeng.test.service.impl;

import java.util.List;

import net.georgezeng.test.dao.BaseDao;
import net.georgezeng.test.service.IBaseService;

public abstract class BaseService<T> implements IBaseService<T> {

  @Override
  public void save(T t) {
    getBaseDao().save(t);
  }

  @Override
  public T get(Long id) {
    return getBaseDao().get(id);
  }

  @Override
  public List<T> findList(T t) {
    return getBaseDao().findList(t);
  }
  
  protected abstract BaseDao<T> getBaseDao();

}
 

(2.2)ContactServiceImpl

package net.georgezeng.test.contact.service;

import net.georgezeng.test.dao.BaseDao;
import net.georgezeng.test.dao.ContactDao;
import net.georgezeng.test.domain.Contact;
import net.georgezeng.test.service.ContactService;
import net.georgezeng.test.service.impl.BaseService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("ContactService")
@Transactional
public class ContactServiceImpl extends BaseService<Contact> implements ContactService {

  @Autowired
  private ContactDao dao;

  @Override
  protected BaseDao<Contact> getBaseDao() {
    return dao;
  }

}

这里使用事务管理使用的是annotation的形式,并且需要在@Service中添加一个ContactService的值,同样也是用于通过spring来发布这个服务时作为引用的bean id。

在上一节中我们还曝露了一个ContactDao的服务,这个地方引用这个服务在代码里是不需要做任何的改变的,因为这个服务的引用注入是在配置文件里完成的(Spring dm提供了引用的annotation方式引入,但是不推荐使用),所以这里照常的Autowired就可以了。

(3)spring配置

(3.1)osgi-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/osgi
		http://www.springframework.org/schema/osgi/spring-osgi.xsd
		http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
        

	<osgi:reference id="contactDao" interface="net.georgezeng.test.dao.ContactDao" />
	
	<osgi:reference id="transactionManager" interface="org.springframework.transaction.PlatformTransactionManager" />
	
	<osgi:service ref="ContactService"
		interface="net.georgezeng.test.service.ContactService" ></osgi:service>


</beans>

这里声明了需要的OSGI服务的引用,我们看到上一节中定义的transactionManager也在这个地方被用到了,因为事务的入口通常就是在service里开始的。

然后这里还曝露了1个ContactService的服务,让web bundle可以使用到这个服务。

(3.2)appContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">


	<context:annotation-config />
	<context:component-scan base-package="net.georgezeng.test" />

	<tx:annotation-driven transaction-manager="transactionManager" />

	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="find*" read-only="true" />
			<tx:method name="*" rollback-for="Exception" />
		</tx:attributes>
	</tx:advice>
	
	<aop:config>
		<aop:pointcut id="serviceCut"
			expression="execution(* net.georgezeng.test..service..*.*(..))" />
		<aop:advisor pointcut-ref="serviceCut" advice-ref="txAdvice" />
	</aop:config>
</beans>

使用了annotation的方式来管理事务,所以定义了下面这个内容:

<tx:annotation-driven transaction-manager="transactionManager" />

虽然我们定义了使用annotation作为事务管理的方式,但是我们可以为整个事务定义一个默认的切面,用来处理默认的事务管理,比如哪些方法只读,或者遇到什么异常回滚等。所以上面定义了一个aop:config和txadvice来做这个事情,并将我们的transactionManager注入。

(4)MANIFEST.MF

(4.1)import


(4.2)export

没有需要export的内容

至此Service Interface Bundle 和 Service Implementation Bundle就开发完成了

附上源码

猜你喜欢

转载自georgezeng.iteye.com/blog/1131184