日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
手寫(xiě)Spring事務(wù)、IOC、DI和MVC

Spring AOP 原理

什么是 AOP?

創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的松北網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

AOP 即面向切面編程,利用 AOP 可以對(duì)業(yè)務(wù)進(jìn)行解耦,提高重用性,提高開(kāi)發(fā)效率

應(yīng)用場(chǎng)景:日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理

AOP 底層實(shí)現(xiàn)原理是采用代理實(shí)現(xiàn)的

Spring 事務(wù)

基本特性:

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

事務(wù)控制分類:

編程式事務(wù):手動(dòng)控制事務(wù)操作

聲明式事務(wù):通過(guò) AOP 控制事務(wù)

編程式事務(wù)實(shí)現(xiàn)

使用編程事務(wù)實(shí)現(xiàn)手動(dòng)事務(wù)

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

    // 獲取事務(wù)源
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;

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

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

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

AOP技術(shù)封裝手動(dòng)事務(wù)

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

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

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

事務(wù)注意事項(xiàng):

一定不要將代碼通過(guò) try 包裹起來(lái),如果程序發(fā)生異常,事務(wù)接收不到異常,就會(huì)認(rèn)為程序正常執(zhí)行,就不會(huì)進(jìn)行回滾,必須手動(dòng)回滾

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

聲明式事務(wù)

通過(guò) AOP 實(shí)現(xiàn),對(duì)方法進(jìn)行攔截,在方法執(zhí)行之前開(kāi)啟事務(wù),結(jié)束后提交事務(wù),發(fā)生異?;貪L事務(wù)

自定義事務(wù)注解

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

}

事務(wù)實(shí)現(xiàn)

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

    private TransactionStatus transactionStatus = null;

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

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

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

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

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

Spring事物傳播行為

  • PROPAGATION_REQUIRED:如果當(dāng)前有事務(wù),就用當(dāng)前事務(wù),如果當(dāng)前沒(méi)有事務(wù),就新建一個(gè)事務(wù)
  • PROPAGATION_SUPPORTS:支持當(dāng)前事務(wù),如果當(dāng)前沒(méi)有事務(wù),就以非事務(wù)方式執(zhí)行
  • PROPAGATION_MANDATORY:支持當(dāng)前事務(wù),如果當(dāng)前沒(méi)有事務(wù),就拋出異常
  • PROPAGATION_REQUIRES_NEW:新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起
  • PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起
  • PROPAGATION_NEVER:以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常

什么是 Spring IOC?

Spring IOC 指的是控制反轉(zhuǎn),IOC 容器負(fù)責(zé)實(shí)例化、定位、配置應(yīng)用程序中的對(duì)象及建立這些對(duì)象間的依賴,交由Spring來(lái)管理這些,實(shí)現(xiàn)解耦

手寫(xiě) Spring IOC

實(shí)現(xiàn)步驟:

掃包

將標(biāo)注了注解的類,通過(guò)反射創(chuàng)建實(shí)例并添加的 bean 容器中

當(dāng)用戶向容器要 bean 時(shí),通過(guò) beanId 在 bean 容器中查找并返回實(shí)例

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 beans = null;

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

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

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

    /**
     * 過(guò)濾標(biāo)注ExtService注解的類
     *
     * @param classes
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private void findAnnotationByClasses(List> 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);
            }
        }
    }

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

    /**
     * 通過(guò)beanId查找對(duì)應(yīng)的實(shí)例
     *
     * @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);
            }
        }
    }

    /**
     * 首字母變小寫(xiě)
     *
     * @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 原理

手寫(xiě) Spring 事務(wù)、IOC、DI 和 MVC

執(zhí)行流程:

  1. 用戶請(qǐng)求 url 至前端控制器 DispatcherServlet

  2. DispatcherServlet 調(diào)用處理器映射器 HandlerMapping

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

  4. DispatcherServlet 根據(jù)處理器 Handler 獲取處理器適配器 HandlerAdapter 執(zhí)行

  5. 執(zhí)行 Handler

  6. 返回 ModelAndView 返回給 DispatcherServlet

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

  8. ViewResolver 解析成具體 View

  9. 渲染視圖

  10. 響應(yīng)頁(yè)面給用戶

Servlet 生命周期

init:在 Servlet 生命周期中,該方法僅執(zhí)行一次,它是在將服務(wù)器裝入 Servlet 時(shí)執(zhí)行的,負(fù)責(zé)初始化 Servlet 對(duì)象,Servlet 是單例多線程的

service:負(fù)責(zé)響應(yīng)請(qǐng)求,每當(dāng)一個(gè)客戶請(qǐng)求一個(gè) HttpServlet 對(duì)象,該對(duì)象的 Service 方法就要被調(diào)用,傳遞一個(gè) ServletRequest 和 ServletResponse 對(duì)象

destroy:在服務(wù)器停止卸載 Servlet 時(shí)調(diào)用

手寫(xiě) Spring MVC

實(shí)現(xiàn)步驟:

創(chuàng)建一個(gè) ExtDispatcherServlet 繼承 HttpServlet

掃包

將標(biāo)注了 @ExtController 注解的類,通過(guò)反射創(chuàng)建對(duì)象添加到容器中,將 beanId 和控制器關(guān)聯(lián)

將標(biāo)注了 @ExtRequestMapping 注解的類,將請(qǐng)求url 和控制器對(duì)象關(guān)聯(lián),將 url 和 方法關(guān)聯(lián)

當(dāng)用戶請(qǐng)求 url 時(shí),查找和 url 對(duì)應(yīng)的對(duì)象,然后查找和 url 對(duì)應(yīng)的方法,執(zhí)行方法,解析并渲染

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;

/**
 * 手寫(xiě)SpringMVC
 */
public class ExtDispatcherServlet extends HttpServlet {
    // 關(guān)聯(lián)beanId和Object
    private ConcurrentHashMap mvcBeans = new ConcurrentHashMap<>();
    // 關(guān)聯(lián)url和控制器對(duì)象
    private ConcurrentHashMap mvcBeanUrl = new ConcurrentHashMap<>();
    // 關(guān)聯(lián)url和methodName
    private ConcurrentHashMap mvcMethodUrl = new ConcurrentHashMap<>();

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

    /**
     * 關(guān)聯(lián)url和控制器對(duì)象、url和methoName
     * @param mvcBeans
     */
    private void handlerMapping(ConcurrentHashMap 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 包內(nèi)所有類
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     */
    private void findClassMVCBeans(List> 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請(qǐng)求
     * @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請(qǐng)求
     * @param req
     * @param resp
     */
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        try {
            doDispatch(req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 路由分發(fā)
     * @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);
    }

    /**
     * 反射執(zhí)行方法
     * @param classInfo 控制器
     * @param object 控制器對(duì)象
     * @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);

        }
    }
}

網(wǎng)站欄目:手寫(xiě)Spring事務(wù)、IOC、DI和MVC
本文網(wǎng)址:http://www.dlmjj.cn/article/pdsscc.html