Spring AOP基于注解的配置

     Spring AOP基于注解的配置,原理跟上篇写的基于xml配置的一样,只是换一种配置方法,注解的方式有时候比xml的方式更容易读懂,加上后面学习的Spring boot,大多都是基于注解形式的配置。

  1. 首先,还是导包,需要导入(Maven导包)
    <dependency>
    	<groupId>org.springframework</groupId>
    	<artifactId>spring-aop</artifactId>
    	<version>4.3.20.RELEASE</version>
    </dependency>
     
  2. 编写需要增强的类UserServiceImpl
    package com.springday.service;
    
    public interface UserService {
    	public void save();
    	
    	public void delete();
    	
    	public void update();
    	
    	public void find();
    }

     

    package com.springday.service;
    
    public class UserServiceImpl implements UserService {
    
    	@Override
    	public void save() {
    		System.out.println("保存操作");
    	}
    
    	@Override
    	public void delete() {
    		System.out.println("删除操作");
    
    	}
    
    	@Override
    	public void update() {
    		System.out.println("更新操作");
    	}
    
    	@Override
    	public void find() {
    		System.out.println("查找操作");
    	}
    
    }
    

     

  3. 在Spring的主配置文件applicationContext.xml开启使用AOP注解配置
    <?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.3.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
    		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
    	
    	 <!-- 导入AOP(约束)命名空间 -->
    	 <!-- 1、配置目标对象 -->
    	 <bean name="userServiceTarget" class="com.springday.service.UserServiceImpl"></bean>
    	 <!-- 2、配置通知对象 -->
    	 <bean name="myAdvice" class="com.springday.annotation.MyAdvice"></bean>
    	<!-- 3、开启使用注解完成织入 -->
    	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    </beans>
    

     

  4. 基于注解配置通知类MyAdvice

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

    如果切入点一样的话,也可以这么写

    package com.springday.annotation;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    
    //通知类
    @Aspect
    //表示该类是一个通知类
    public class MyAdvice {
    	
    	@Pointcut("execution(* com.springday.service..*Service.*(..))")
    	public void pc() {}
    
    	//指定该方法是前置通知,并且制定切入点
    	@Before("MyAdvice.pc()")
    	public void before(){
    		System.out.println("这是前置通知!!");
    	}
    	//后置通知
    	@AfterReturning("MyAdvice.pc()")
    	public void afterReturning(){
    		System.out.println("这是后置通知(如果出现异常不会调用)!!");
    	}
    	//环绕通知
    	@Around("MyAdvice.pc()")
    	public Object around(ProceedingJoinPoint pjp) throws Throwable {
    		System.out.println("这是环绕通知之前的部分!!");
    		Object proceed = pjp.proceed();//调用目标方法
    		System.out.println("这是环绕通知之后的部分!!");
    		return proceed;
    	}
    	//异常通知
    	@AfterThrowing("MyAdvice.pc()")
    	public void afterException(){
    		System.out.println("出事啦!出现异常了!!");
    	}
    	//后置通知
    	@After("MyAdvice.pc()")
    	public void after(){
    		System.out.println("这是后置通知(出现异常也会调用)!!");
    	}
    }
    
    

     

  5.  编写测试类进行测试

    package com.springday.annotation;
    
    import javax.annotation.Resource;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import com.springday.service.UserService;
    
    //创建容器
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:com/springday/annotation/applicationContext.xml")
    public class Demo {
    	
    	@Resource(name="userServiceTarget")
    	private UserService us;
    	
    
    	@Test //测试注解
    	public void fun1() {
    		us.find();
    	}
    }
    

     

  6. 运行结果 

     

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值