国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Spring切面簡記及應(yīng)用(spring aop)

2019-11-08 02:33:29
字體:
供稿:網(wǎng)友

概念

面向切面編程:把邏輯代碼和處理瑣碎事務(wù)的代碼分離開,以便能夠分離復(fù)雜度。

切面(AOP)術(shù)語

1.連接點(Joinpoint)

2.切點(Pointcut)

3.增強(Advice)

Before advice

After returning advice

After throwing advice

After(finally) advice

Around advice

4.目標對象(Target)

5.引入(Introduction)

6.織入(Weaving)

7.代理(PRoxy)

8.切面(aspect)

優(yōu)點

更清晰的代碼邏輯,業(yè)務(wù)邏輯只關(guān)注自己本身,不用去管瑣碎的事情,比如:安全,日志,事務(wù)等等。

可以減少代碼量

想了解概念的同學(xué)可以去百度或者先看下面的demo 再理解

應(yīng)用

maven依賴

<dependency>	<groupId>org.aspectj</groupId>	<artifactId>aspectjrt</artifactId>	<version>1.8.6</version></dependency><dependency>	<groupId>org.aspectj</groupId>	<artifactId>aspectjweaver</artifactId>	<version>1.8.6</version></dependency>

這里我只提供切面需要的依賴

如果不懂maven的同學(xué) 可以先看本站的教程

準備工作

// 接口public interface IUserDao {	void save(Person person);}@Component   // 加入容器public class UserDao implements IUserDao{	@Override	public void save(Person person) {		System.out.println("-----核心業(yè)務(wù):保存!!!------"); 	}}public class Person {	private String name;	private String sex;	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public String getSex() {		return sex;	}	public void setSex(String sex) {		this.sex = sex;	}}

切面配置

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:p="http://www.springframework.org/schema/p"    xmlns:context="http://www.springframework.org/schema/context"    xmlns:aop="http://www.springframework.org/schema/aop"    xsi:schemaLocation="        http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop.xsd">		<!-- 開啟注解掃描 -->	<context:component-scan base-package="net.begincode.aop_anno"></context:component-scan>		<!-- 開啟動態(tài)代理 -->    <aop:aspectj-autoproxy proxy-target-class="true"/></beans>

指定切面

@Component@Aspect  // 指定當前類為切面類public class Aop {	// 指定切入點表達式: 攔截哪些方法; 即為哪些類生成代理對象	@Pointcut("execution(* net.begincode.aop_anno.*.*(..))")	public void pointCut_(){	}		// 前置通知 : 在執(zhí)行目標方法之前執(zhí)行	@Before("pointCut_()")	public void begin(){		System.out.println("開始事務(wù)/異常");	}		// 后置/最終通知:在執(zhí)行目標方法之后執(zhí)行  【無論是否出現(xiàn)異常最終都會執(zhí)行】	@After("pointCut_()")	public void after(){		System.out.println("提交事務(wù)/關(guān)閉");	}		// 返回后通知: 在調(diào)用目標方法結(jié)束后執(zhí)行 【出現(xiàn)異常不執(zhí)行】	@AfterReturning("pointCut_()")	public void afterReturning() {		System.out.println("afterReturning()");	}		// 異常通知: 當目標方法執(zhí)行異常時候執(zhí)行此關(guān)注點代碼	@AfterThrowing("pointCut_()")	public void afterThrowing(){		System.out.println("afterThrowing()");	}		// 環(huán)繞通知:環(huán)繞目標方式執(zhí)行	@Around("pointCut_()")	public void around(ProceedingJoinPoint pjp) throws Throwable{		Object[] objs = pjp.getArgs();		Person p = (Person) objs[0];		System.out.println(p.getName());		System.out.println("環(huán)繞前....");		pjp.proceed();  // 執(zhí)行目標方法		System.out.println("環(huán)繞后....");	}	}

使用junit測試

applicationContext ac = new ClassPathXmlApplicationContext("net/begincode/aop_anno/bean.xml");@Testpublic void testApp() {	IUserDao userDao = (IUserDao) ac.getBean("userDao");	System.out.println(userDao.getClass());//$Proxy001  	Person person = new Person();	person.setName("abc");	person.setSex("man");	userDao.save(person);}

輸出:

class com.sun.proxy.$Proxy15abc環(huán)繞前....開始事務(wù)/異常-----核心業(yè)務(wù):保存!!!------環(huán)繞后....提交事務(wù)/關(guān)閉afterReturning()

如果目標對象有實現(xiàn)接口,spring會自動選擇"JDK代理"

如果目標對象沒有實現(xiàn)接口,spring就會使用"cglib"代理

AOP的應(yīng)用很廣泛 功能很強大 可以做:安全,日志,事務(wù)等等。

這里介紹的只是最基本使用方法

參考文獻:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

具體應(yīng)用

在begincode 問答系統(tǒng)中 我們利用切面去攔截controller,使指定的入?yún)⒈粩r截

@Aspect@Componentpublic class RequestAspect {    @Pointcut("execution(* net.begincode.controller.*.*(..))")    public void pointCut_() {    }    @Around("pointCut_()")    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {        Object[] objects = proceedingJoinPoint.getArgs();        for (int i = 0; i < objects.length; i++) {            if (objects[i] instanceof ProblemLabelParam) {                ProblemLabelParam problemLabelParam = (ProblemLabelParam) objects[i];                problemLabelParam.check();            }        }        return proceedingJoinPoint.proceed();    }}

攔截所有從controller進去的參數(shù) 并且驗證有沒有 ProblemLabelParam 類型的參數(shù)

如果有的話,則調(diào)用其中的check方法驗證傳入的參數(shù)是否有異常

部分代碼如下:

public class ProblemLabelParam extends Param{ .... @Override    public void check() {        checkNotEmpty(problem.getContent(),ProblemResponseEnum.PROBLEM_ADD_ERROR);        checkNotEmpty(problem.getTitle(),ProblemResponseEnum.PROBLEM_ADD_ERROR);    } ....     }

我們規(guī)定入?yún)ο蟊仨毴坷^承Param類 不能使用原有的model直接進入方法

并且實現(xiàn)抽象的check方法

public abstract class Param {    public abstract void check();    public void checkNotNull(Object value, ResponseEnum status) {        checkArgs(value != null, status);    }    public void checkNotEmpty(String value, ResponseEnum status) {        checkArgs(StringUtils.isNotBlank(value), status);    }    public void checkArgs(boolean success, ResponseEnum status) {        if (!success) {            throw new BizException(status);        }    }}


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 龙江县| 华阴市| 阳新县| 册亨县| 桃源县| 乳源| 宜昌市| 子长县| 乐清市| 合肥市| 长白| 开封市| 沙河市| 兴城市| 古浪县| 南宫市| 岑溪市| 柯坪县| 若尔盖县| 鄂尔多斯市| 昆山市| 怀安县| 辽宁省| 保定市| 卓资县| 股票| 天等县| 武汉市| 中宁县| 信宜市| 合肥市| 霍邱县| 鹰潭市| 仪征市| 五大连池市| 日土县| 永定县| 渭南市| 竹溪县| 凌云县| 望谟县|