博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring-AOP(面向切面编程)-xml方式配置
阅读量:5174 次
发布时间:2019-06-13

本文共 4683 字,大约阅读时间需要 15 分钟。

AOP是针对面向对象编程的一种补充,有时使用面向对象不能很好完成一些额外的功能业务时,可以采用AOP来进行补充。

AOP术语:

  1. 切面(Aspect)

    切面是用于编写切面逻辑的一个类,这个类很类似于JDK动态代理中的回调处理器或者cglib中的方法拦截器,主要就是将需要增强目标对象的功能代码编写在这个类中,而这些功能增强的代码就是切面逻辑。

  2. 切入点(Pointcut)

    切入点类似一个切入的坐标,目的就是要找到目标对象的哪些方法。

    通常切入点都是以一种表达式的形式来描述

  3. 通知/增强(Advice)

    通知就是切面中具体的增强逻辑,总共分为五种:

    1)前置通知(在目标方法调用之前执行)

    2)后置通知(在目标方法正确返回之后执行)

    3)环绕通知(在目标方法调用前后执行)

    4)异常通知(当目标方法抛出异常时执行,并且不会执行后置通知)

    5)最终通知(不管目标方法有无异常都会执行)

  4. 连接点(Joinpoint)

    目标对象的方法就称之为连接点,一个切入点可以对应目标对象的的多个连接点。

  5. 代理(Proxy)

    在运行时动态创建的对象,称之为代理对象,负责调用目标对象的方法,并执行增强功能

  6. 目标(Target)

    被代理的对象就是目标对象

  7. 织入(Weaver)

    将切面中的通知应用到目标对象上并且产生代理的过程称之为织入。

    因此通常描述为“将通知织入到具体的目标”。


 

项目结构:

 

代码示例:

applicationContext.xml配置:

 

切面(增强)类:

package edu.nf.ch11.service.aspect;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.Signature;import org.aspectj.lang.reflect.MethodSignature;import javax.xml.crypto.dsig.SignatureMethod;/** * @author wangl * @date 2018/10/23 * 编写一个UserService的切面 * 在切面中编写的方法都称之为通知或者是增强 * 在AOP当中,通知有五种类型 * 1. 前置通知 * 2. 后置通知 * 3. 环绕通知 * 4. 最终通知 * 5. 异常通知 * 在一个切面中,任何一种类型的通知都可以定义多个,当有多个通知存在的时候 * 就会形成一个通知栈 */public class UserServiceAspect {    /**     * 前置通知     * 在执行目标方法之前执行,拦截目标方法的参数     * 可以通过JoinPoint获得目标方法的参数信息     */    public void before(JoinPoint joinPoint){        System.out.println("前置通知...");        //通过连接点获得目标对象        //joinPoint.getTarget();        //获取目标方法的参数信息        Object[] params = joinPoint.getArgs();        for (Object param : params) {            System.out.println(param);        }    }    /**     * 后置通知     * 在目标方法执行完并且return之后执行     */    public void afterReturn(String returnVal){        System.out.println("后置通知..."+returnVal);    }    /**     * 环绕通知     * @param pjp 连接点处理器,由它负责调用目标对象的具体方法     *     */    public Object around(ProceedingJoinPoint pjp) throws Throwable {        System.out.println("环绕通知前...");        //调用目标对象的方法        Object returnVal = pjp.proceed();        //获取目标方法的参数        System.out.println(pjp.getArgs()[0]);        //通过MethodSignature获取连接点方法信息        MethodSignature ms = (MethodSignature)pjp.getSignature();        //获取正在调用的目标方法        System.out.println(ms.getMethod().getName());        //获取目标方法的返回类型        System.out.println(ms.getReturnType());        System.out.println("环绕通知后...");        return returnVal;    }    /**     * 异常通知     * @param e 获取目标方法抛出的异常对象     */    public void throwAdvice(Throwable e){        System.out.println("异常通知..."+e.getMessage());    }    /**     * 最终通知     */    public void after(){        System.out.println("最终通知...");    }}

 

 

 UserService接口:

package edu.nf.ch11.service;/** * @author wangl * @date 2018/10/23 */public interface UserService {    /**     * 添加用户     */    void addUser();    /**     * 删除用户     * @param uid     */    void deleteUser(String uid);    /**     * 查询用户     * @param uid     * @return     */    String getUserNameById(String uid);}

 

UserServiceImpl实现类:

package edu.nf.ch11.service.impl;import edu.nf.ch11.service.UserService;/** * @author wangl * @date 2018/10/23 * 目标对象(被代理的对象) * Spring的AOP中需要代理的所有目标对象都应该归纳在ioc容器中管理 */public class UserServiceImpl implements UserService {    @Override    public void addUser() {        System.out.println("保存用户信息");    }    @Override    public void deleteUser(String uid) {        System.out.println("删除用户,ID:" + uid);    }    @Override    public String getUserNameById(String uid) {        System.out.println("根据ID查询用户名");        //System.out.println(10/0);        return "user1";    }}

 

程序测试类:

package edu.nf.ch11.test;import edu.nf.ch11.service.UserService;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/** * @author wangl * @date 2018/10/23 */public class UserServiceAspectTest {    @Test    public void testAddUser(){        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");        //这里从容器中获取的对象是一个代理对象        UserService service = context.getBean("userService", UserService.class);        //service.addUser();        //System.out.println("----------------------");        //service.deleteUser("10001");        //System.out.println("----------------------");        service.getUserNameById("10001");    }}

 

 运行结果

 

转载于:https://www.cnblogs.com/hhmm99/p/9835791.html

你可能感兴趣的文章
毕业后的五年拉开大家差距的原因(肖雪)
查看>>
Java集合大全
查看>>
接口限流算法
查看>>
HDU - 2845 Beans
查看>>
html设置背景图片并自适应
查看>>
深入研究C语言 第一篇(续)
查看>>
数字 字符串 转换
查看>>
Git时光机穿梭之撤销修改
查看>>
雷林鹏分享:MySQL 插入数据
查看>>
C#设计模式之抽象工厂
查看>>
NOSQL
查看>>
Oracle存储过程由例子到理论
查看>>
正因为我们是前端,所以代码更需要优雅
查看>>
实验四 主存空间的分配和回收
查看>>
LeetCode 14. 最长公共前缀(Longest Common Prefix)
查看>>
Ubuntu 12.04 编译最新版u-boot-2012.04
查看>>
Access转Sqlite的最简单的方法(不需要DB Manager)
查看>>
cordova AndroidStudio3.0 升级报错问题
查看>>
【译】10个机器学习的JavaScript示例
查看>>
虚拟机的三种网络模式
查看>>