spring再学习之AOP实操

Posted 小南天门

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring再学习之AOP实操相关的知识,希望对你有一定的参考价值。

一、spring导包

   

2、目标对象

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、准备通知

//通知类
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、配置进行织入

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xmlns="http://www.springframework.org/schema/beans" 
       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-4.2.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-4.2.xsd 
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">      


<!-- 导入安aop(约束)命名空间 -->
<!-- 1.配置目标对象 -->
     <bean name="userServiceTarget" class="cn.itcast.service.UserServiceImpl"></bean>
<!-- 2.配置通知对象 -->
     <bean name="myAdvice" class="cn.itcast.d_springaop.MyAdvice"></bean>
<!-- 3.配置将通知织入目标对象 -->
     <aop:config>
          <!-- 配置切入点 
书写
expression="execution(* cn.itcast.service.*ServiceImpl.*(..))"
public void cn.itcast.service.UserServiceImpl.save()
                             一般 public省略掉 ,一般对返回值不做要求用*表示,类下的放大,用*表示全部的方法
          * cn.itcast.service.UserServiceImpl.*()
                             继续演化..表示不对参数有任何要求
          * cn.itcast.service.UserServiceImpl.*(..)
                               继续演化,不对集体的类有要求
          * cn.itcast.service.*ServiceImpl.*(..)  
                              继续演化  ,不只找service中的类而且找子包
            * cn.itcast.service..*ServiceImpl.*(..)                                
          -->
<aop:pointcut expression="execution(* cn.itcast.service.*ServiceImpl.*(..))" id="pc"/> <aop:aspect ref="myAdvice"> <aop:before method="before" pointcut-ref="pc"/> <aop:after-returning method="afterReturning" pointcut-ref="pc"/> <aop:around method="around" pointcut-ref="pc"/> <aop:after method="after" pointcut-ref="pc"/> <aop:after-throwing method="afterException" pointcut-ref="pc"/> </aop:aspect> </aop:config> </beans>

测试:

/**
 * @RunWith :帮我们创建容器
 * @ContextConfiguration :指定创建容器时使用哪个配置文件
 * @author zws
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:cn/itcast/e_annotationaop/applicationContext.xml")
public class Demo {
    
    @Resource(name="userServiceTarget")  
    private UserService us;
    
    @Test
    public void fun1(){
        us.save();
    }

}

结果:

这是环绕通知之前的部分
这是前置通知!!!
保存用户!
这是环绕通知之后的部分
出事了,出现异常了
这是后置通知(如果出现异常不会调用)!!!

注解配置:

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

配置:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns
="http://www.springframework.org/schema/beans"
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-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "
> <!-- 导入安aop(约束)命名空间 --> <!-- 1.配置目标对象 --> <bean name="userServiceTarget" class="cn.itcast.service.UserServiceImpl"></bean> <!-- 2.配置通知对象 --> <bean name="myAdvice" class="cn.itcast.e_annotationaop.MyAdvice"></bean> <!-- 3.配置将通知织入目标对象 使用注解完成织如--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>

测试:

/**
 * @RunWith :帮我们创建容器
 * @ContextConfiguration :指定创建容器时使用哪个配置文件
 * @author zws
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:cn/itcast/e_annotationaop/applicationContext.xml")
public class Demo {
    
    @Resource(name="userServiceTarget")  
    private UserService us;
    
    @Test
    public void fun1(){
        us.save();
    }

}

结果;

这是环绕通知之前的部分
这是前置通知!!!
保存用户!
这是环绕通知之后的部分
出事了,出现异常了
这是后置通知(如果出现异常不会调用)!!!

 

 

 

以上是关于spring再学习之AOP实操的主要内容,如果未能解决你的问题,请参考以下文章

spring再学习之AOP准备

spring再学习之基本概念

spring 学习之二 AOP编程

Spring阶段性学习总结AOP编程入门学习之动态代理实现代码的优化

Spring学习之第一个AOP程序

Spring学习之AOP