日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

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

發布時間:2023/12/3 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在JavaEE中使用CDI的简单面向方面的编程(AOP) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們編寫滿足特定業務邏輯的服務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;} }

讓我們創建一個公開兩種方法的數據訪問對象–

  • 獲取所有人的細節
  • 獲取給定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個步驟:

  • 創建Interceptor綁定,該綁定創建帶@InterceptorBinding注釋的注釋,該注釋用于綁定攔截器代碼和需要攔截的目標代碼。
  • 創建一個用@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;} }

    上面的代碼中有兩個有趣的事情:

  • 使用@AroundInvoke
  • 傳遞給方法的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綁定和被執行的攔截器。 現在讓我們創建服務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中使用CDI的简单面向方面的编程(AOP)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。