Karaf教程第9部分基于注解的blueprint和JPA

来源:互联网 发布:ubuntu mod dav svn 编辑:程序博客网 时间:2024/05/19 16:21

Karaf教程第9部分基于注解的blueprint和JPA

本部分演示如何用模型持久层和基于CDI注解的UI创建一个小的应用。

1 blueprint-maven-plugin

编写blueprint xml文件是很繁琐的,太大的blueprint xml文件很难与代码修改保持同步,尤其是代码重构。所以很多人喜欢使用注解来进行声明。理想情况下,这些注解应该被标准化,这样就很清晰地定义注解的功能。maven-blueprint-plugin允许使用注解配置blueprint。它会扫描一个或多个路径下的注解类,然后target/generated-resources创建blueprint.xml文件。请参阅maven-blueprint-plugin文档。

2 示例tasklist-blueprint-cdi

本部分演示如何用模型持久层和UI创建一个小的应用,而完全不用手动编写blueprint xml文件。

Github源代码地址:Karaf-Tutorial/tasklist-cdi-blueprint

2.1 工程结构

  • features
  • model
  • persistence
  • ui

2.2 创建bundle

这些bundle都是使用maven-bundle-plugin创建的。这个创建只在父工程使用,它会用<_include>osgi.bnd</_include>抽取OSGi配置到单独的文件。所以每一个bundle工程只需要空的、可包含额外配置的osgi.bnd文件。

由于bnd会自动计算出大多部分配置,因此osgi.bnd文件一般都比较小。

2.3 Features

定义karaf feature,安装示例以及必要的依赖。

2.4 模型

Model工程定义了Task为一个jpa实体,定义了服务接口TaskService。由于model工程不需要任何依赖注入,所以不涉及到blueprint-maven-plugin

Task JPA Entity

@Entity

public class Task {

    @Id

    Integer id;

    String title;

    String description;

    Date dueDate;

    boolean finished;

    // Getters and setters omitted

}

TaskService (Task的CRUD操作)

public interface TaskService {

    Task getTask(Integer id);

    void addTask(Task task);

    void updateTask(Task task);

    void deleteTask(Integer id);

    Collection<Task> getTasks();

}

persistence.xml

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

 

    <persistence-unit name="tasklist" transaction-type="JTA">

        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <jta-data-source>osgi:service/tasklist</jta-data-source>

        <properties>

            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>

            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>

        </properties>

    </persistence-unit>

 

</persistence>

Persistence.xml文件定义了持久单元的名字为"tasklist",使用JTA事务。jta-data-source元素指向一个DataSource服务"tasklist"jndi名字。所以除了JTA DataSource名字,它是一个标准的hibernate 4.3风格的持久化定义,自动创建schema

另一个比较重要的事情是maven-bundle-plugin插件的配置。

配置maven bundle plugin

<Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>

<Import-Package>*, org.hibernate.proxy, javassist.util.proxy</Import-Package>

Meta-Persistence指向一个persistence.xml文件, 它用于触发aries jpa创建这个BundleEntityManagerFactoryImport-Package配置导入了两个packagehibernate在运行时优化处理时需要。由于在编译时,这个优化是未知的,所以需要给maven-bundle-plugin一些提示。

2.5 持久化

tasklist-cdi-persistence bundle是这个示例当中第一个使用blueprint-maven-plugin的模块。在pom文件中,我们设置搜索路径为"net.lr.tasklist.persistence.impl"。所以所有在这个包或者子包中的类都会被扫描。

pom文件中,我们需要一个maven-bundle-plugin的特殊配置:
<Import-Package>!javax.transaction, *, javax.transaction;version="[1.1,2)"</Import-Package>
在依赖中,我们使用事务API1.2作为包含@Transactional注解的第一个规范版本。在运行时,虽然我们不需要这个注解,且karaf只提供事务API1.1版本。所以我们调整import使用karaf提供的版本。一旦事务API 1.2版本可用,这一行就不再需要了。

TaskServiceImpl

@OsgiServiceProvider(classes = {TaskService.class})

@Singleton

@Transactional

public class TaskServiceImpl implements TaskService {

    @PersistenceContext(unitName="tasklist")

    EntityManager em;

    @Override

    public Task getTask(Integer id) {

        return em.find(Task.class, id);

    }

    @Override

    public void addTask(Task task) {

        em.persist(task);

        em.flush();

    }

    // Other methods omitted

}

TaskServiceImpl使用了很多注解。使用注解@Singleton标记这个类为blueprint bean。使用注解@OsgiServiceProvider标记这个类为接口TaskServiceOSGi服务。使用注解@Transactional标记这个类支持事务操作。

所有的方法都在jta事务中执行。这意味着如果没有事务,那就会创建出来一个事务。如果已经有一个事务,那么方法就会参与其中。在事务的边界,事务要么被提交,要么因为异常而被回滚。

EntityManager用于持久单元"tasklist",被注入到字段em。它为每一个方法透明地提供一个EntityManager,按需创建,并在事务边界关闭。

InitHelper

@Singleton

public class InitHelper {

    Logger LOG = LoggerFactory.getLogger(InitHelper.class);

    @Inject TaskService taskService;

    @PostConstruct

    public void addDemoTasks() {

        try {

            Task task = new Task(1, "Just a sample task", "Some more info");

            taskService.addTask(task);

        } catch (Exception e) {

            LOG.warn(e.getMessage(), e);

        }

    }

}

InitHelper类不是严格必须的。它只是简单滴创建和持久化第一个任何,这样UI就可以显示一些东西了。

@Singleton注解标记这个类作为一个blueprint bean创建。
@Inject TaskService taskService
注入在blueprint上下文中找到的第一个类型为TaskServicebean,并赋给字段taskService
@PostConstruct
注解确保在这个bean的所有字段都被注入后,调用addDemoTasks()方法。

另一件有趣的事情是模块中的测试类TaskServiceImplTest。它在OSGi之外运行,使用特殊的persistence.xml用于测试时创建EntityManagerFactory,而不需要jndi DataSource,因为这个很难提供。它也使用了RESOURCE_LOCAL事务,这样我们就不需要创建事务管理。测试注入了普通的EntityManger对象到TaskServiceImpl类中。所以我们必须手动开启事务和提交事务。这个例子说明了用普通的java测试JPA代码,测试简单快速。

2.6 Servlet UI

tasklist-ui模块使用OSGi service TaskServicePax-web whiteboard bundle会检测导出的servlet,并使用HttpService发布它。在pom文件中,这个模块需要blueprint-maven-plugin有适当的scanPath

TasklistServlet

@OsgiServiceProvider(classes={Servlet.class})

@Properties({@Property(name="alias", value="/tasklist")})

@Singleton

public class TaskListServlet extends HttpServlet {

    @Inject @OsgiService

    TaskService taskService;

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,

        IOException {

        // Actual code omitted

    }

}

TaskListServlet用接口javax.servlet.Servlet导出,服务属性别名为"/tasklist"。这样,通过http://localhost:8181/tasklist就可以访问到。

@Inject @OsgiService TaskService taskService这条语句会创建一个blueprint的引用元素,导入TaskService接口定义的OSGI服务。然后,这个服务就被注入到上面这个类的taskService字段。如果这个接口存在多个服务实例,那么filter属性可用于选择使用哪一个。

 

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 研究生开学已经不是团员了怎么办 毕业了要搬宿舍怎么办 中专学历认证已停止怎么办 中专不做学历认证考试怎么办 大学生欠学费被扣毕业证怎么办 考警校体检没过怎么办 美国签证申请预约名字写错怎么办 当兵不从学校走怎么办 门牙崩了一小块怎么办 遇到很难过的事情怎么办 小孩子上课精力不集中怎么办 每天工作都很累压力大怎么办 重体力活搬不动怎么办 大学没参加体测怎么办 英文写的很丑怎么办 患有勃起障碍应该怎么办较好 运动过度小腿肌肉酸痛怎么办 高考有纹身是字怎么办 新生儿测听力没过关怎么办 色弱高考体检时没查出来怎么办 公司福利体检查二对半怎么办 高考体检表复印件丢了怎么办 高考体检表身高填错了怎么办 大学档案高考体检表丢了怎么办 工厂组织体检我有乙肝怎么办 我有乙肝单位组织体检怎么办? 矮腰袜子老掉怎么办 短腰袜子老下滑怎么办 中考体检结果丢了怎么办 咳嗽左胸围一处刺痛怎么办? 阴茎小父母催婚怎么办 头发扎进指甲缝怎么办 指甲缝扎流血了怎么办 中考考差了高中怎么办 骨折后我抽烟了怎么办 五年级科学考不好怎么办 考试连续考差了怎么办 客户说没考虑好怎么办 小孩生殖器痒经常用手抓怎么办 孩子在幼儿园生殖器官受伤怎么办? 被骗了3000块钱怎么办 小说