这一节进入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
引入了3个关联的项目,分别是dao2,domain和service
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就开发完成了
附上源码