Spring中AOP基本概念及配置方式

AOP概念

AOP基本概念

  • 连接点(JoinPoint):在AOP中表示“在哪里干”
  • 切入点(Pointcut):在AOP中表示“在哪里干的集合”,可以认为是连接点的集合
  • 通知(Advice):在AOP中表示为“干什么”,在Spring中主要包括:前置通知(before advice)、后置通知(after advice)以及环绕通知(around advice)
  • 切面(Aspect):在AOP中表示“在哪里干和干什么的集合”
  • 目标对象(Target Object):在AOP中表示“对谁干”
  • **AOP代理(AOP Proxy):**AOP框架使用代理模式创建的对象,从而实现在连接点处插入通知(即应用切面),就是通过代理来对目标对象应用切面。在Spring中,AOP代理可以用JDK动态代理或CGLIB代理实现,而通过拦截器模型应用切面。
  • 织入(Weaving):织入是一个过程,就是
    将切面应用到目标对象从而创建出AOP代理对象的过程,织入可以在编译期、类装载期和运行期进行

Spring中通过Schema方式配置AOP

  1. beans.xml基本配置

    <bean id="helloWorldService" class="com.javacl.spring_learn.aop.HelloWordService"></bean>
    <bean id="aspect" class="com.javacl.spring_learn.aop.HelloAspect"></bean>
    
    <aop:config>
        <aop:pointcut expression="execution(* com.javacl.spring_learn..*.*(..))" id="poincut"/>
        <aop:aspect ref="aspect">
            <aop:before method="beforeAdvice" pointcut-ref="poincut"/>
            <aop:after method="afterFinallyAdvice" pointcut-ref="poincut"/>
        </aop:aspect>       
    </aop:config>
  2. 切面类基本配置
public class HelloAspect {

    //前置通知
    public void beforeAdvice() {
        System.out.println("=======before advice");
    }

    //后置最终通知
    public void afterFinallyAdvice() {
        System.out.println("=======after finally advice");
    }
}
  1. 接口类类基本配置
public interface IHelloWorldService {
    public void sayHello();
}
  1. 目标对象类基本配置
public class HelloWordService implements IHelloWorldService {

    public void sayHello() {
        System.out.println("=======Hello World");
    }
}
  1. 测试类
public class AopTest {

    @Test
    public void testHelloWorld() {
        BeanFactory bf = new ClassPathXmlApplicationContext("beans.xml");
        IHelloWorldService helloWorldService = bf.getBean("helloWorldService", IHelloWorldService.class);
        helloWorldService.sayHello();
    }
}

Spring中通过注解方式配置AOP

  1. 启动对@AspectJ注解的支持
<!-- 启用对Aspectj的支持 -->
<aop:aspectj-autoproxy />
  1. 定义切面类
/**
 * 声明切面
 * 
 * @author caoliang
 *
 */
@Aspect
@Component
public class MyInterceptor {

    /**
     * 声明切入点Pointcut
     */
    @Pointcut("execution (* com.javacl.spring_learn.aspectj..*.add*(..))")
    public void pointCut() {

    }

    /**
     * 前置通知
     * @param param
     */
    @Before("pointCut() && args(param)")
    public void beforeAdvice(String param) {
        System.out.println("这是一个前置通知" + param);
    }


    /**
     * 后置通知
     * @param result
     */
    @AfterReturning(pointcut = "pointCut()", returning = "result")
    public void returnAfterAdvice(String result) {
        System.out.println("这是一个后置通知 result:" + result);
    }

    /**
     * 最终通知
     */
    @After("pointCut()")
    public void afer() {
        System.out.println("最终通知");
    }

    /**
     * 异常通知
     * @param joinPoint
     * @param exception
     */
    @AfterThrowing(pointcut = "pointCut()", throwing = "exception")
    public void throwingException(JoinPoint joinPoint, Exception exception) {
        // 获取被调用的类名
        String targetClassName = joinPoint.getTarget().getClass().getName();
        // 获取被调用的方法名
        String targetMethodName = joinPoint.getSignature().getName();

        String logInfo = "异常通知:执行" + targetClassName + "类的" + targetMethodName + "方法时发生异常";

        System.out.println(logInfo);
    }

    /**
     * 环绕通知
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around(value="pointCut()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        String targetMethodName = proceedingJoinPoint.getSignature().getName();
        System.out.println("环绕通知开始");
        Object object = proceedingJoinPoint.proceed();
        String logInfo = "环绕通知结束:" + targetMethodName;
        System.out.println(logInfo);
        return object;
    }
}
  1. 接口及接口实现类
public interface IUserService {
    public String add(String name);
}

@Service(value="userService")
public class UserService implements IUserService {

    public String add(String name) {
        System.out.println("add " + name + " success");
        //throw new RuntimeException();
        return "add user success";
    }
}
  1. 测试方法
@Test
    public void testUserAdd() {
        BeanFactory bf = new ClassPathXmlApplicationContext("beans.xml");
        IUserService userService = bf.getBean("userService", IUserService.class);
        userService.add("caoliang");
    }


  1. 测试结果

环绕通知开始
这是一个前置通知caoliang
add caoliang success
环绕通知结束:add
最终通知
这是一个后置通知 result:add user success

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值