spring框架实现aop编程 使用注解方式自动扫描生成代理实现编程并且测试

spring不仅可以通过使用xml标签的方式实现,生成切面,还可以通过注解方式声明切面。

基于注解方式声明切面,实现AOP编程

采用注解方式实现(Annotation)步骤:

  1. 先在beans.xml文件中引用aop schema,然后启动代理自动生成的扫描配置
  2. 拦截器进行注解开发
  3. 拦截器和service都要在beans.xml文件中配置

xml文件注解详细表:

@Before在被代理对象的方法前先调用,属于前置通知。
@AfterReturning在被代理对象的方法正常返回后调用,属于返回通知(也等于后置通知)如果发生异常则不会被调用
@Around在被代理对象的方法封装起来,并用环绕通知取代它,属于环绕通知,它将覆盖原有的方法,但是允许你通过反射调用原有方法。环绕通知是Spring AOP中最强大的通知,它可以同时实现前置和后置的通知,它保留了调度被代理对象原有方法的功能,所以它强大,又灵活。这个通知里有一个参数ProceedingJoinPoint,是Spring提供的一个参数,使它可以反射连接点。当环绕通知使用proceed()方法后会先调用前置通知,然后反射切点方法,最后就是后置通知和返回(或者异常)通知。
@AfterThrowing在被调用对象的方法抛出异常后调用,属于异常通知,要求被代理对象的方法执行过程中产生异常
@After在被代理对象的方法后调用,属于后置通知

配置拦截器

使用注解方法进行aop编程,必须要有一个私有的,无返回值的、没有方法体的方法:
private void add() {}//这个方法要求私有,不能有返回值,不能有参数

package interceptor;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
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 ExtendFilter {
	private Logger log = Logger.getLogger("service.BookServiceImpl");
	
	@Pointcut("execution(* service..*.*(..))")  
	private void add() {}//这个方法要求私有,不能有返回值,不能有参数
	//("execution(* service..*.*(..))") 
	//括号里面的参数表示:切入点是service包及其子包的所有方法,不管有没有返回值
	/**
	 * 对访问权限进行控制的方法  前置通知
	 */
	@Before("add()")
	public void access()
	{
		log.log(Level.INFO, "前置通知:在调用方法前输出");
	}
	
	/**
	 * 进行异常处理的方法  异常通知
	 */
	public void handleException()
	{
		log.log(Level.INFO,"异常通知:出现异常时输出");
	}
	
	/**
	 * 获取ip地址的方法  后置通知
	 */
	@After("add()")
	public void getIp()
	{
		log.log(Level.INFO,"后置通知:在调用方法后输出");
	}
	
	/**
	 * 环绕通知输出,那么这个方法很特殊,需要获取目标对象的相关参数
	 */
	@Around("add()")
	public Object writeLog(ProceedingJoinPoint joinpoint)
	{
		log.log(Level.INFO,"环绕通知(前):---------------");
		Object obj=null;
		try {
			obj=joinpoint.proceed();//调用目标对象方法
		} catch (Throwable e) {
			e.printStackTrace();
		}
		log.log(Level.INFO,"环绕通知(后):---------------");
		return obj;
	}
}

配置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: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:aspectj-autoproxy></aop:aspectj-autoproxy>
 	<!-- 目标对象 -->
 	<bean id="bookService" class="service.BookServiceImpl"></bean>
 	<!-- 拦截器 -->
 	<bean id="extendFilter" class="interceptor.ExtendFilter"></bean>
 </beans>

编写目标对象的接口

package service;

public interface BookServiceIfac {
	void addBook(String name);
}

编写目标类,并且事项刚刚写的接口

package service;

public class BookServiceImpl implements BookServiceIfac {
	
	@Override
	public void addBook(String name)
	{
		System.out.println("添加了图书,书名为  :"+name);
	}
}

编写测试类

package test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import service.BookServiceIfac;
import service.ProductService;

public class Test {

	public static void main(String[] args) {

		ApplicationContext act = new ClassPathXmlApplicationContext("beans.xml");
		BookServiceIfac bookService = (BookServiceIfac) act.getBean("bookService");
		bookService.addBook("水浒传!");
	}
}

查看控制台,看输出结果:

在这里插入代码片

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code_mo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值