javaee编程题

我们编写满足特定业务逻辑的服务API。 涵盖所有服务API(如安全性,日志记录,审核,度量延迟等)的跨领域问题很少。 这是一个重复的非业务代码,可以在其他方法之间重用。 重用的一种方法是将这些重复代码移入其自己的方法,并在服务API中调用它们,例如:

public class MyService{public ServiceModel service1(){isAuthorized();//execute business logic.}
}public class MyAnotherService{public ServiceModel service1(){isAuthorized()://execute business logic. }
}

上面的方法会起作用,但不会在不产生代码噪音的情况下起作用,将横切关注点与业务逻辑混合在一起。 有另一种方法可以通过使用Aspect来解决上述要求,这种方法称为面向方面的编程(AOP)。 您可以使用AOP的不同方式-通过使用Spring AOP,JavaEE AOP。 在此示例中,我将尝试在Java EE应用程序中使用使用CDI的AOP。 为了解释这一点,我选择了一个非常简单的示例,该示例构建一个Web应用程序以从Database中获取少量记录并显示在浏览器中。

创建数据访问层

表结构为:

create table people(id INT NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL,place varchar(100),primary key(id));

让我们创建一个Model类来保存个人信息

package demo.model;
public class Person{private String id;private String name;private String place;public String getId(){ return id; } public String setId(String id) { this.id = id;}public String getName(){ return name; } public String setName(String name) { this.name = name;}public String getPlace(){ return place; } public String setPlace(String place) { this.place = place;}
}

让我们创建一个公开两种方法的数据访问对象–

  1. 获取所有人的细节
  2. 获取一个给定ID的人的详细信息
package demo.dao;import demo.common.DatabaseConnectionManager;
import demo.model.Person;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;public class PeopleDAO {public List<Person> getAllPeople() throws SQLException {String SQL = "SELECT * FROM people";Connection conn = DatabaseConnectionManager.getConnection();List<Person> people = new ArrayList<>();try (Statement statement = conn.createStatement();ResultSet rs = statement.executeQuery(SQL)) {while (rs.next()) {Person person = new Person();person.setId(rs.getString("id"));person.setName(rs.getString("name"));person.setPlace(rs.getString("place"));people.add(person);}}return people;}public Person getPerson(String id) throws SQLException {String SQL = "SELECT * FROM people WHERE id = ?";Connection conn = DatabaseConnectionManager.getConnection();try (PreparedStatement ps = conn.prepareStatement(SQL)) {ps.setString(1, id);try (ResultSet rs = ps.executeQuery()) {if (rs.next()) {Person person = new Person();person.setId(rs.getString("id"));person.setName(rs.getString("name"));person.setPlace(rs.getString("place"));return person;}}}return null;}
}

您可以使用自己的方法来获取新的连接。 在上面的代码中,我创建了一个静态实用程序,该实用程序返回了相同的连接。

创建拦截器

创建拦截器涉及2个步骤:

  1. 创建Interceptor绑定,该绑定创建带有@InterceptorBinding注释的注释,该注释用于绑定拦截器代码和需要拦截的目标代码。
  2. 创建一个用@Interceptor注释的类,其中包含拦截器代码。 它包含用@AroundInvoke注释的方法,不同的生命周期注释, @AroundTimeout等。

让我们通过名称@LatencyLogger创建一个拦截器绑定

package demo;import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.*;
import static java.lang.annotation.ElementType.*;
import javax.interceptor.InterceptorBinding;@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface LatencyLogger {}

现在我们需要创建Interceptor代码,该代码以@Interceptor注释,并以上面创建的Interceptor绑定进行注释,即@LatencyLogger

package demo;
import java.io.Serializable;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;@Interceptor
@LatencyLogger
public class LatencyLoggerInterceptor implements Serializable{@AroundInvokepublic Object computeLatency(InvocationContext invocationCtx) throws Exception{long startTime = System.currentTimeMillis();//execute the intercepted method and store the return valueObject returnValue = invocationCtx.proceed();long endTime = System.currentTimeMillis();System.out.println("Latency of " + invocationCtx.getMethod().getName() +": " + (endTime-startTime)+"ms");return returnValue;}
}

上面的代码中有两个有趣的事情:

  1. 使用@AroundInvoke
  2. 传递给方法的InvocationContext类型的参数

@AroundInvoke将方法指定为拦截器方法。 一个Interceptor类只能有一个带有此注释的方法。 每当目标方法被拦截时,其上下文都会传递给拦截器。 使用InvocationContext可以获取方法的详细信息,并将参数传递给该方法。

我们需要在WEB-INF / beans.xml文件中声明以上拦截器

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"bean-discovery-mode="all"><interceptors><class>demo.LatencyLoggerInterceptor</class></interceptors>
</beans>

创建带有拦截器注释的服务API

我们已经创建了Interceptor绑定和被执行的拦截器。 现在让我们创建Service API,然后使用Interceptor绑定对其进行注释

/** To change this license header, choose License Headers in Project Properties.* To change this template file, choose Tools | Templates* and open the template in the editor.*/
package demo.service;import demo.LatencyLogger;
import demo.dao.PeopleDAO;
import demo.model.Person;
import java.sql.SQLException;
import java.util.List;
import javax.inject.Inject;public class PeopleService {@InjectPeopleDAO peopleDAO;@LatencyLoggerpublic List<Person> getAllPeople() throws SQLException {return peopleDAO.getAllPeople();}@LatencyLoggerpublic Person getPerson(String id) throws SQLException {return peopleDAO.getPerson(id);}}

我们已经使用Interceptor绑定@LatencyLogger注释了服务方法。 另一种方法是在类级别进行注释,然后将注释应用于类的所有方法。 还要注意的另一件事是@Inject批注,该批注注入实例,即将依赖项注入到类中。

接下来是连接Controller和View以显示数据。 控制器是servlet,视图是使用JSTL标记的纯JSP。

/** To change this license header, choose License Headers in Project Properties.* To change this template file, choose Tools | Templates* and open the template in the editor.*/
package demo;import demo.model.Person;
import demo.service.PeopleService;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet(name = "AOPDemo", urlPatterns = {"/AOPDemo"})
public class AOPDemoServlet extends HttpServlet {@InjectPeopleService peopleService;@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {try {List<Person> people = peopleService.getAllPeople();Person person = peopleService.getPerson("2");request.setAttribute("people", people);request.setAttribute("person", person);getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);} catch (SQLException ex) {Logger.getLogger(AOPDemoServlet.class.getName()).log(Level.SEVERE, null, ex);}}
}

上面的servlet可从http:// localhost:8080 /获得。

/ AOPDemo。 它获取数据并重定向到视图以显示该数据。 请注意,该服务也已使用@Inject注释注入。 如果没有注入依赖项,而是使用new创建依赖项,则拦截器将无法工作。 这是我在构建此样本时意识到的重要一点。

呈现数据的JSP将是

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>AOP Demo</title></head><body><h1>Hello World!</h1><table><tr><th>Id</th><th>Name</th><th>Place</th></tr><c:forEach items="${requestScope.people}" var="person"><tr><td><c:out value="${person.id}"/></td><td><c:out value="${person.name}"/></td><td><c:out value="${person.place}"/></td></tr></c:forEach></table><br/>Details for person with id=2<c:out value="Name ${person.name} from ${person.place}" /></body>
</html>

这样,您将可以使用Interceptor构建一个非常简单的应用程序。 感谢您的阅读,并一直与我在一起。 请分享您的查询/反馈作为评论。 并在您的朋友之间分享这篇文章!

翻译自: https://www.javacodegeeks.com/2014/09/simple-aspect-oriented-programming-aop-using-cdi-in-javaee.html

javaee编程题

javaee编程题_在JavaEE中使用CDI的简单面向方面的编程(AOP)相关推荐

  1. 在JavaEE中使用CDI的简单面向方面的编程(AOP)

    我们编写满足特定业务逻辑的服务API. 涵盖所有服务API(如安全性,日志记录,审核,度量延迟等)的跨领域问题很少. 这是一个重复的非业务代码,可以在其他方法之间重用. 重用的一种方法是将这些重复的代 ...

  2. java关于hashmap编程题_在Java中,关于HashMap类的描述,以下说法错误的是( )。...

    [单选题]住宅之外其他民用建筑按照建筑高度分类 ,( )m以上,称为超高层建筑 [判断题]串行通信波特率是衡量数据传输速率的参数. [单选题]CC2530的AD转换器支持多达14位的模拟数字转换,它有 ...

  3. Java编程题_面向对象和常用API01_B级

    Java编程题_面向对象和常用API01_B级 第1题 面向对象.异常.集合.IO 题干: 请编写程序,完成键盘录入学生信息,并计算总分将学生信息与总分一同写入文本文件 需求:键盘录入3个学生信息(姓 ...

  4. 环评师c语言题目,C语言考试——编程题_文库吧

    C语言考试--编程题_文库吧 2020-09-27 08:21:23 [导读]该数本身,比如153=13+53+33,故153是水仙花数).要求将判断某数是否素数的功.能编成一个独立的函数,然后在ma ...

  5. Linux环境编程姜林美,Linux环境编程习题_编程题_答案.pdf

    Linux环境编程习题_编程题_答案 Linux 境编程-人民邮电出版社-姜林美 课后习题(编程题)答案 第三章 1 第五章 4 第六章 9 第七章 19 第八章 22 第九章 35 第十章 38 三 ...

  6. pta中java编程题_多文件编程题

    多文件编程题与函数题相似,区别是裁判编写的判题程序可能涉及多个文件,因此不是写在题干里,而是以附件的形式供学生下载,方便学生调试.学生须按照题干上给出的要求编写程序,完成指定功能.学生的提交也可能包含 ...

  7. 数据结构面试题编程题_您下次编程面试时应该了解的顶级数据结构

    数据结构面试题编程题 by Fahim ul Haq 通过Fahim ul Haq Niklaus Wirth, a Swiss computer scientist, wrote a book in ...

  8. java在线编程题_阿里笔试题(2017在线编程题)-- 数串分组 --Java实现

    看到有人写了阿里的面试题,心里痒痒,好久 没搞过这些了,写着实现一下 题目 2017年3月阿里在线编程题(实习内推) 给定一串数字 判断是否存在这三个元素,它们将数字串分为四个子串,其中每个子串的数字 ...

  9. javascript编程题_如何开始使用JavaScript进行竞争性编程

    javascript编程题 by Priyabrata Biswas 通过Priyabrata Biswas 如何开始使用JavaScript进行竞争性编程 (How to get started w ...

最新文章

  1. 如何使用OpenCV自动校正文本图像
  2. Spring2.5的新特性
  3. 未能加载文件或程序集“Antlr3.Runtime”或它的某一个依赖项。参数错误。 (异常来自 HRESULT:0x80070057 (E_INVALIDARG))解决方法。...
  4. CH 5102 Mobile Service(线性DP)
  5. python中abc属于字符串吗_在Python中,字符串s = 'abc',那么执行表达式s+'d'之后,s的打印结果是( )。...
  6. JDBC编程专题9之JDBC事务
  7. netmiko可以连接的设备有哪些_气体报警器可以联动哪些设备
  8. Struts2学习笔记(十六) 文件上传(File Upload)
  9. 《深入理解Spark:核心思想与源码分析》——1.3节阅读环境准备
  10. 方差(Variance)和标准差(Standard Deviation)
  11. #脚本实现宠物动作行为_短视频剧情创作方法有哪些?爆款短视频的标配,只需88个脚本模板...
  12. java学习笔记宋红康版本-01
  13. 软件测试的艺术——软件测试的原则
  14. ZigBee-CC2530单片机 - 1路硬件PWM控制舵机角度(精度为1us)
  15. IETester的使用(针对VB.NET视频)
  16. 技术成长-不积跬步无以至千里
  17. RL(Chapter 3): Finite Markov Decision Processes (有限马尔可夫决策过程)
  18. K3 Wise 常用表【转载】
  19. 数据包络分析-CEA碳减排有关文献分析(第一篇)
  20. P1873 砍树 【二分】

热门文章

  1. jzoj3844-统计损失【树形dp,换根法】
  2. bzoj2226-[Spoj5971]LCMSum【欧拉函数,GCD】
  3. P1220-关路灯【区间dp】
  4. jzoj3510-最短路径【dp】
  5. codeforces1485 F. Copy or Prefix Sum(dp)
  6. Codeforces Round #674 (Div. 3)
  7. 【DP】【四边形不等式】邮局(P4767)
  8. 【线段树】Optimal Insertion(CF751E)
  9. NOIP2013货车运输
  10. 8、mybatis中的sql映射文件详解(3)