91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

手寫 Spring 事務、IOC、DI 和 MVC

發布時間:2020-05-04 22:45:59 來源:網絡 閱讀:3451 作者:灰白世界 欄目:編程語言

Spring AOP 原理

什么是 AOP?

AOP 即面向切面編程,利用 AOP 可以對業務進行解耦,提高重用性,提高開發效率

應用場景:日志記錄,性能統計,安全控制,事務處理,異常處理

AOP 底層實現原理是采用代理實現的

Spring 事務

基本特性:

  • 原子性
  • 隔離性
  • 一致性
  • 持久性

事務控制分類:

編程式事務:手動控制事務操作

聲明式事務:通過 AOP 控制事務

編程式事務實現

使用編程事務實現手動事務

@Component
@Scope("prototype")
public class TransactionUtils {

    // 獲取事務源
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;

    // 開啟事務
    public TransactionStatus begin() {
        TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
        return transaction;
    }

    // 提交事務
    public void commit(TransactionStatus transaction) {
        dataSourceTransactionManager.commit(transaction);
    }

    // 回滾事務
    public void rollback(TransactionStatus transaction) {
        dataSourceTransactionManager.rollback(transaction);
    }
}

AOP技術封裝手動事務

@Component
@Aspect
public class TransactionAop {
    @Autowired
    private TransactionUtils transactionUtils;

    @Around("execution(* com.kernel.service.UserService.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) {

        try {
            // 調用方法之前執行
            System.out.println("開啟事務");
            TransactionStatus transactionStatus = transactionUtils.begin();
            proceedingJoinPoint.proceed();
            System.out.println("提交事務");
            transactionUtils.commit(transactionStatus);
        } catch (Throwable throwable) {
            System.out.println("回滾事務");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }
}

事務注意事項:

一定不要將代碼通過 try 包裹起來,如果程序發生異常,事務接收不到異常,就會認為程序正常執行,就不會進行回滾,必須手動回滾

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

聲明式事務

通過 AOP 實現,對方法進行攔截,在方法執行之前開啟事務,結束后提交事務,發生異常回滾事務

自定義事務注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExtTransaction {

}

事務實現

@Component
@Aspect
public class TransactionAop {
    @Autowired
    private TransactionUtils transactionUtils;

    private TransactionStatus transactionStatus = null;

    /**
     * AOP實現事務管理
     *
     * @param proceedingJoinPoint 切面通知對象
     */
    @Around("execution(* com.kernel.service.*.* (..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint)  {
        try {
            // 獲取注解對象
            ExtTransaction extTransaction = getExtTransaction(proceedingJoinPoint);
            begin(extTransaction);
            // 執行目標方法
            proceedingJoinPoint.proceed();
            // 提交事務
            commit();
        } catch (Throwable throwable) {
            transactionUtils.rollback();
        }
    }

    /**
     * 獲取注解對象
     *
     * @param proceedingJoinPoint 切面通知對象
     * @return 注解對象
     * @throws NoSuchMethodException
     */
    public ExtTransaction getExtTransaction(ProceedingJoinPoint proceedingJoinPoint) throws NoSuchMethodException {
        // 獲取方法名稱
        String method = proceedingJoinPoint.getSignature().getName();
        // 獲取目標方法
        Class<?> classTarget = proceedingJoinPoint.getTarget().getClass();
        // 獲取目標對象類型
        Class[] parameterTypes = ((MethodSignature) proceedingJoinPoint.getSignature()).getParameterTypes();
        // 獲取目標對象方法
        Method objMethod = classTarget.getMethod(method, parameterTypes);
        // 獲取注解
        ExtTransaction declaredAnnotation = objMethod.getDeclaredAnnotation(ExtTransaction.class);
        return declaredAnnotation;
    }

    /**
     * 開啟事務
     * @param extTransaction 注解對象
     * @return 事務對象
     */
    TransactionStatus begin(ExtTransaction extTransaction) {
        if (extTransaction != null)
            transactionStatus = transactionUtils.begin();
        return transactionStatus;
    }

    /**
     * 提交事務
     */
    void commit() {
        if (transactionStatus != null)
            transactionUtils.commit(transactionStatus);
    }

    /**
     * 回滾事務
     */
    void rollback() {
        transactionUtils.rollback();
    }
}

Spring事物傳播行為

  • PROPAGATION_REQUIRED:如果當前有事務,就用當前事務,如果當前沒有事務,就新建一個事務
  • PROPAGATION_SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行
  • PROPAGATION_MANDATORY:支持當前事務,如果當前沒有事務,就拋出異常
  • PROPAGATION_REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起
  • PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起
  • PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常

什么是 Spring IOC?

Spring IOC 指的是控制反轉,IOC 容器負責實例化、定位、配置應用程序中的對象及建立這些對象間的依賴,交由Spring來管理這些,實現解耦

手寫 Spring IOC

實現步驟:

掃包

將標注了注解的類,通過反射創建實例并添加的 bean 容器中

當用戶向容器要 bean 時,通過 beanId 在 bean 容器中查找并返回實例

package com.kernel.ext;

import com.kernel.ext.annotation.ExtAutoWired;
import com.kernel.ext.annotation.ExtService;
import com.kernel.utils.ClassUtil;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * IOC 注解版本
 */
public class ExtClassPathXmlApplicationContext {
    // 包名
    private String packageName;
    // bean容器
    private ConcurrentHashMap<String, Object> beans = null;

    /**
     * 構造函數
     *
     * @param packageName 包名
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public ExtClassPathXmlApplicationContext(String packageName) throws InstantiationException, IllegalAccessException {
        this.packageName = packageName;
        init();
    }

    /**
     * 初始化對象
     *
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    private void init() throws IllegalAccessException, InstantiationException {
        // 遍歷所有類
        List<Class<?>> classes = ClassUtil.getClasses(packageName);

        // 將所有標注ExtService注解的類加入到容器中
        findAnnotationByClasses(classes);
    }

    /**
     * 過濾標注ExtService注解的類
     *
     * @param classes
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private void findAnnotationByClasses(List<Class<?>> classes) throws InstantiationException, IllegalAccessException {
        for (Class classInfo : classes) {
            ExtService extService = (ExtService) classInfo.getAnnotation(ExtService.class);
            if (extService != null) {
                Object newInstance = newInstance(classInfo);
                beans.put(toLowerCaseFirstOne(classInfo.getSimpleName()), newInstance);
            }
        }
    }

    /**
     * 通過反射構建對象
     *
     * @param classInfo
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private Object newInstance(Class classInfo) throws InstantiationException, IllegalAccessException {
        return classInfo.getClass().newInstance();
    }

    /**
     * 通過beanId查找對應的實例
     *
     * @param beanId
     * @return
     */
    public Object getBean(String beanId) throws IllegalAccessException {
        Object object = null;
        if (StringUtils.isEmpty(beanId))
            return null;
        for (String id : beans.keySet())
            if (beanId.equals(id)) {
                object = beans.get(beanId);
                attrAssign(object);
                break;
            }
        return object;
    }

    /**
     * 依賴注入
     */
    void attrAssign(Object object) throws IllegalAccessException {
        Class<?> aClass = object.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            ExtAutoWired extAutoWired = field.getAnnotation(ExtAutoWired.class);
            if (extAutoWired != null) {
                field.setAccessible(true);
                Object bean = getBean(field.getName());
                field.set(field.getName(), object);
            }
        }
    }

    /**
     * 首字母變小寫
     *
     * @param s
     * @return
     */
    public static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0)))
            return s;
        else {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append(Character.toLowerCase(s.charAt(0)));
            stringBuffer.append(s.substring(1));
            return stringBuffer.toString();
        }
    }
}

Spring MVC 原理

手寫 Spring 事務、IOC、DI 和 MVC

執行流程:

  1. 用戶請求 url 至前端控制器 DispatcherServlet

  2. DispatcherServlet 調用處理器映射器 HandlerMapping

  3. HandlerMapping 根據 url 找到具體的處理器生成處理器執行鏈,并將執行鏈返回給 DispatcherServlet

  4. DispatcherServlet 根據處理器 Handler 獲取處理器適配器 HandlerAdapter 執行

  5. 執行 Handler

  6. 返回 ModelAndView 返回給 DispatcherServlet

  7. DispatcherServlet 將 ModelAnd view 傳遞給視圖解析器 ViewResolver

  8. ViewResolver 解析成具體 View

  9. 渲染視圖

  10. 響應頁面給用戶

Servlet 生命周期

init:在 Servlet 生命周期中,該方法僅執行一次,它是在將服務器裝入 Servlet 時執行的,負責初始化 Servlet 對象,Servlet 是單例多線程的

service:負責響應請求,每當一個客戶請求一個 HttpServlet 對象,該對象的 Service 方法就要被調用,傳遞一個 ServletRequest 和 ServletResponse 對象

destroy:在服務器停止卸載 Servlet 時調用

手寫 Spring MVC

實現步驟:

創建一個 ExtDispatcherServlet 繼承 HttpServlet

掃包

將標注了 @ExtController 注解的類,通過反射創建對象添加到容器中,將 beanId 和控制器關聯

將標注了 @ExtRequestMapping 注解的類,將請求url 和控制器對象關聯,將 url 和 方法關聯

當用戶請求 url 時,查找和 url 對應的對象,然后查找和 url 對應的方法,執行方法,解析并渲染

package com.kernel.ext.servlet;

import com.kernel.controller.ExtIndexController;
import com.kernel.ext.annotation.ExtController;
import com.kernel.ext.annotation.ExtRequestMapping;
import com.kernel.utils.ClassUtil;
import org.apache.commons.lang.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 手寫SpringMVC
 */
public class ExtDispatcherServlet extends HttpServlet {
    // 關聯beanId和Object
    private ConcurrentHashMap<String, Object> mvcBeans = new ConcurrentHashMap<>();
    // 關聯url和控制器對象
    private ConcurrentHashMap<String, Object> mvcBeanUrl = new ConcurrentHashMap<>();
    // 關聯url和methodName
    private ConcurrentHashMap<String, String> mvcMethodUrl = new ConcurrentHashMap<>();

    /**
     * 初始化Servlet
     */
    public void init() {
        try {
            List<Class<?>> classes = ClassUtil.getClasses("com.kernel.controller");
            findClassMVCBeans(classes);
            handlerMapping(mvcBeans);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 關聯url和控制器對象、url和methoName
     * @param mvcBeans
     */
    private void handlerMapping(ConcurrentHashMap<String, Object> mvcBeans) {
        for (Object classInfo : mvcBeans.values()) {
            ExtRequestMapping extCla***equestMapping = classInfo.getClass().getDeclaredAnnotation(ExtRequestMapping.class);
            String requestBaseUrl = null;
            if (extCla***equestMapping != null) {
                requestBaseUrl = extCla***equestMapping.value();
            }
            Method[] methods = classInfo.getClass().getDeclaredMethods();
            for (Method method : methods) {
                ExtRequestMapping extMthodRequestMapping = method.getDeclaredAnnotation(ExtRequestMapping.class);
                if (extCla***equestMapping != null){
                    String httpRequestUrl = extMthodRequestMapping.value();
                    mvcBeanUrl.put(requestBaseUrl + httpRequestUrl, classInfo);
                    mvcMethodUrl.put(requestBaseUrl + httpRequestUrl, method.getName());
                }
            }
        }

    }

    /**
     * 將所有控制器添加到mvcBeans中
     * @param classes 包內所有類
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     */
    private void findClassMVCBeans(List<Class<?>> classes) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        for (Class classInfo : classes) {
            ExtController extController = (ExtController) classInfo.getDeclaredAnnotation(ExtController.class);
            if (extController != null){
                mvcBeans.put(classInfo.getName(), ClassUtil.newInstance(classInfo));
            }
        }
    }

    /**
     * get請求
     * @param req
     * @param resp
     * @throws IOException
     * @throws ServletException
     */
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
        try {
            doPost(req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * post請求
     * @param req
     * @param resp
     */
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        try {
            doDispatch(req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 路由分發
     * @param req
     * @param resp
     * @throws Exception
     */
    private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        String requestUrl = req.getServletPath();
        Object object = mvcBeanUrl.get(requestUrl);
        if (object == null)
            object = ExtIndexController.class.newInstance();
        String methodName = mvcMethodUrl.get(requestUrl);
        if (StringUtils.isEmpty(methodName))
            methodName = "error";
        Class<?> classInfo = object.getClass();
        String resultPage = (String) methodInvoke(classInfo, object, methodName);
        viewDisplay(resultPage, req, resp);
    }

    /**
     * 視圖渲染
     * @param resultPage
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    private void viewDisplay(String resultPage, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String suffix = ".jsp";
        String prefix = "/";
        req.getRequestDispatcher(prefix + resultPage + suffix).forward(req, resp);
    }

    /**
     * 反射執行方法
     * @param classInfo 控制器
     * @param object 控制器對象
     * @param methodName 方法名稱
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     */
    private Object methodInvoke(Class<?> classInfo, Object object, String methodName) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        Method method = null;
        try {
            method = classInfo.getDeclaredMethod(methodName);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        finally {
            return method.invoke(object);

        }
    }
}
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

额济纳旗| 平阳县| 海丰县| 北宁市| 皋兰县| 阿拉善盟| 绥棱县| 罗源县| 湖口县| 永城市| 朝阳县| 明溪县| 博客| 云浮市| 平阳县| 资讯| 清原| 和林格尔县| 辛集市| 云阳县| 葫芦岛市| 宁强县| 满洲里市| 自治县| 巴林右旗| 云浮市| 潢川县| 湄潭县| 昭通市| 隆子县| 榆中县| 巩留县| 昭苏县| 清涧县| 津市市| 平江县| 丰城市| 连山| 开阳县| 江阴市| 阿勒泰市|