Spring中的AOP配置(xml和注解)

AOP

AOP概念

思想介绍

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

spring实现aop的原理

在这里插入图片描述

名词学习

在这里插入图片描述

步骤(xml配置)

1.导包

4(核心)+2(Spring AOP)+2(第三方AOP)

在这里插入图片描述

2.准备目标对象

UseServiceImpl.java

package com.eilas.service;

public class UserServiceImpl implements UserService{
    @Override
    public void save() {
        System.out.println("保存用户!");
        //int i = 1/0;
    }
    @Override
    public void delete() {
        System.out.println("删除用户!");
    }
    @Override
    public void update() {
        System.out.println("更新用户!");
    }
    @Override
    public void find() {
        System.out.println("查找用户!");
    }
}

3.准备通知

MyAdvice.java

package com.eilas.d_springaop;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAdvice {
    //前置通知	
//		|-目标方法运行之前调用
    //后置通知(如果出现异常不会调用)
//		|-在目标方法运行之后调用
    //环绕通知
//		|-在目标方法之前和之后都调用
    //异常拦截通知
//		|-如果出现异常,就会调用
    //后置通知(无论是否出现 异常都会调用)
//		|-在目标方法运行之后调用
//----------------------------------------------------------------
    
    //前置通知
    public void before(){
        System.out.println("这是前置通知!!");
    }
    //后置通知
    public void afterReturning(){
        System.out.println("这是后置通知(如果出现异常不会调用)!!");
    }
    //环绕通知
    public Object around(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("这是环绕通知之前的部分!!");
        Object proceed = pjp.proceed();//调用目标方法
        System.out.println("这是环绕通知之后的部分!!");
        return proceed;
    }
    //异常通知
    public void afterException(){
        System.out.println("出事啦!出现异常了!!");
    }
    //后置异常通知
    public void after(){
        System.out.println("这是后置通知(出现异常也会调用)!!");
    }

}

4.配置进行织入,将通知织入目标对象中

applicationContext.xml

<?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: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">

    <!-- 准备工作: 导入aop(约束)命名空间 -->
    <!-- 1.配置目标对象 -->
    <bean name="userServiceTarget" class="com.eilas.service.UserServiceImpl"/>
    <!-- 2.配置通知对象 -->
    <bean name="myAdvice" class="com.eilas.d_springaop.MyAdvice"/>
    <!-- 3.开启使用注解完成织入 -->
    <aop:config>
        <!--配置切入点
          public void com.eilas.service.UserServiceImpl.save() //public可以省略
          void com.eilas.service.UserServiceImpl.save() //一般不对返回值做要求
          * com.eilas.service.UserServiceImpl.save() //但我们想不止对save方法做切入 ->
          * com.eilas.service.UserServiceImpl.*()  //但是这个必须是空参数的,我们想 ->
          * com.eilas.service.UserServiceImpl.*(..) //对参数不做要求,但这个只针对UserServiceImpl类,
          最终形态
          * com.eilas.service.*ServiceImpl.*(..) //对服务类切入
          * com.eilas.service..*ServiceImpl.*(..) //包括子包,但一般用不着
        -->
        <aop:pointcut id="pc" expression="execution(* com.eilas.service.*ServiceImpl.*(..))"/>

        <aop:aspect ref="myAdvice">
            <!--指定名为before方法作为前置通知-->
            <aop:before method="before" pointcut-ref="pc"/>
            <!--后置-->
            <aop:after-returning method="afterReturning" pointcut-ref="pc"/>
            <!--环绕-->
            <aop:around method="around" pointcut-ref="pc"/>
            <!--异常拦截-->
            <aop:after-throwing method="afterException" pointcut-ref="pc"/>
            <!--后置异常-->
            <aop:after method="after" pointcut-ref="pc"/>
        </aop:aspect>
    </aop:config>
</beans>

MyAdvice.java

package com.eilas.d_springaop;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAdvice {
    //前置通知
    public void before(){
        System.out.println("这是前置通知!!");
    }
    //后置通知
    public void afterReturning(){
        System.out.println("这是后置通知(如果出现异常不会调用)!!");
    }
    //环绕通知
    public Object around(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("这是环绕通知之前的部分!!");
        Object proceed = pjp.proceed();//调用目标方法
        System.out.println("这是环绕通知之后的部分!!");
        return proceed;
    }
    //异常通知
    public void afterException(){
        System.out.println("出事啦!出现异常了!!");
    }
    //后置异常通知
    public void after(){
        System.out.println("这是后置通知(出现异常也会调用)!!");
    }

}

5.测试

package com.eilas.d_springaop;

import com.eilas.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/eilas/d_springaop/applicationContext.xml")
public class AopTest {
    @Resource(name = "userService")
    UserService us;

    @Test
    public void test01() {
        us.save();
    }
}

步骤(注解)

1,2,一样

3.注解通知

package com.eilas.e_annotationaop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

//通知类 //表示该类是一个通知类
@Aspect
public class MyAdvice {
    @Pointcut("execution(* com.eilas.service.*ServiceImpl.*(..))")
    public void pc() {}
    //前置通知
//		|-目标方法运行之前调用
    //后置通知(如果出现异常不会调用)
//		|-在目标方法运行之后调用
    //环绕通知
//		|-在目标方法之前和之后都调用
    //异常拦截通知
//		|-如果出现异常,就会调用
    //后置通知(无论是否出现 异常都会调用)
//		|-在目标方法运行之后调用
//----------------------------------------------------------------
    //前置通知
    //指定该方法是前置通知,并制定切入点
    @Before("MyAdvice.pc()")
    public void before(){
        System.out.println("这是前置通知!!");
    }
    //后置通知
    @AfterReturning("execution(* com.eilas.service.*ServiceImpl.*(..))")
    public void afterReturning(){
        System.out.println("这是后置通知(如果出现异常不会调用)!!");
    }
    //环绕通知
    @Around("execution(* com.eilas.service.*ServiceImpl.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("这是环绕通知之前的部分!!");
        Object proceed = pjp.proceed();//调用目标方法
        System.out.println("这是环绕通知之后的部分!!");
        return proceed;
    }
    //异常通知
    @AfterThrowing("execution(* com.eilas.service.*ServiceImpl.*(..))")
    public void afterException(){
        System.out.println("出事啦!出现异常了!!");
    }
    //后置异常通知
    @After("execution(* com.eilas.service.*ServiceImpl.*(..))")
    public void after(){
        System.out.println("这是后置通知(出现异常也会调用)!!");
    }

}


4.配置进行织入,将通知织入目标对象中

<?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: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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 准备工作: 导入aop(约束)命名空间 -->
    <!-- 1.配置目标对象 -->
    <bean name="userService" class="com.eilas.service.UserServiceImpl"/>
    <!-- 2.配置通知对象 -->
    <bean name="myAdvice" class="com.eilas.e_annotationaop.MyAdvice"/>
    <!-- 3.开启使用注解完成织入 -->
    <aop:aspectj-autoproxy/>
</beans>

5.测试

package com.eilas.e_annotationaop;

import com.eilas.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/eilas/e_annotationaop/applicationContext.xml")
public class AopTest {
    @Resource(name = "userService")
    UserService us;

    @Test
    public void test01() {
        us.save();
    }
}

发布了25 篇原创文章 · 获赞 5 · 访问量 1146

猜你喜欢

转载自blog.csdn.net/tinfengyee/article/details/88928198