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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
手寫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 可以對業(yè)務(wù)進(jìn)行解耦,提高重用性,提高開發(fā)效率

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

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

Spring 事務(wù)

基本特性:

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

事務(wù)控制分類:

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

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

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

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

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

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

    // 開啟事務(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("開啟事務(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):

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

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

聲明式事務(wù)

通過 AOP 實(shí)現(xiàn),對方法進(jìn)行攔截,在方法執(zhí)行之前開啟事務(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 切面通知對象
     */
    @Around("execution(* com.kernel.service.*.* (..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint)  {
        try {
            // 獲取注解對象
            ExtTransaction extTransaction = getExtTransaction(proceedingJoinPoint);
            begin(extTransaction);
            // 執(zhí)行目標(biāo)方法
            proceedingJoinPoint.proceed();
            // 提交事務(wù)
            commit();
        } catch (Throwable throwable) {
            transactionUtils.rollback();
        }
    }

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

    /**
     * 開啟事務(wù)
     * @param extTransaction 注解對象
     * @return 事務(wù)對象
     */
    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)前沒有事務(wù),就新建一個(gè)事務(wù)
  • PROPAGATION_SUPPORTS:支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行
  • PROPAGATION_MANDATORY:支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(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)用程序中的對象及建立這些對象間的依賴,交由Spring來管理這些,實(shí)現(xiàn)解耦

手寫 Spring IOC

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

掃包

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

當(dāng)用戶向容器要 bean 時(shí),通過 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();
    }

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

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

    /**
     * 過濾標(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);
            }
        }
    }

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

    /**
     * 通過beanId查找對應(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);
            }
        }
    }

    /**
     * 首字母變小寫
     *
     * @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 事務(wù)、IOC、DI 和 MVC

執(zhí)行流程:

  1. 用戶請求 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)頁面給用戶

Servlet 生命周期

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

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

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

手寫 Spring MVC

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

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

掃包

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

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

當(dāng)用戶請求 url 時(shí),查找和 url 對應(yīng)的對象,然后查找和 url 對應(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;

/**
 * 手寫SpringMVC
 */
public class ExtDispatcherServlet extends HttpServlet {
    // 關(guān)聯(lián)beanId和Object
    private ConcurrentHashMap mvcBeans = new ConcurrentHashMap<>();
    // 關(guān)聯(lián)url和控制器對象
    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和控制器對象、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請求
     * @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();
        }
    }

    /**
     * 路由分發(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 控制器對象
     * @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)頁題目:手寫Spring事務(wù)、IOC、DI和MVC
文章鏈接:http://www.dlmjj.cn/article/pdsscc.html