Java笔记(九):AOP

AOP是指Aspect Oriented Programming 面向切面编程

AOP本质上就是动态代理 将一些常用功能从每个业务方法中剥离出来

写法如下

首先引入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>${spring.version}</version>
</dependency>

然后定义一个切面

@Aspect
@Component
public class LoggingAspect {
    // 在执行UserService的每个方法前执行:
    @Before("execution(public * com.itranswarp.learnjava.service.UserService.*(..))")
    public void doAccessCheck() {
        System.err.println("[Before] do access check...");
    }

    // 在执行MailService的每个方法前后执行:
    @Around("execution(public * com.itranswarp.learnjava.service.MailService.*(..))")
    public Object doLogging(ProceedingJoinPoint pjp) throws Throwable {
        System.err.println("[Around] start " + pjp.getSignature());
        Object retVal = pjp.proceed();
        System.err.println("[Around] done " + pjp.getSignature());
        return retVal;
    }
}

除了使用@Component注解之外,还使用了@Aspect注解,那么它被@Before@Around注解的方法将被注入到后面字符串表示的位置执行

Before表示UserService这个Bean的所有public方法之前

Around表示MailService所有public方法的前后

我们需要在Configuration上加一个@EnableAspectJAutoProxy注解

拦截器类型:

  • @Before:这种拦截器先执行拦截代码,再执行目标代码。如果拦截器抛异常,那么目标代码就不执行了;
  • @After:这种拦截器先执行目标代码,再执行拦截器代码。无论目标代码是否抛异常,拦截器代码都会执行;
  • @AfterReturning:和@After不同的是,只有当目标代码正常返回时,才执行拦截器代码;
  • @AfterThrowing:和@After不同的是,只有当目标代码抛出了异常时,才执行拦截器代码;
  • @Around:能完全控制目标代码是否执行,并可以在执行前后、抛异常后执行任意拦截代码,可以说是包含了上面所有功能。

在装配AOP时,最好使用注解来表明bean被装配了 比如使用@Transactional来表明Bean在数据库事务中被调用

例子

定义一个注解或者使用已经存在的注解

@Target(METHOD)
@Retention(METHOD)
public @interface AspectMehod {
	String value();
}

在需要切面的地方进行标注

@Component
public class UserService {
	//监控register()方法性能;
	@AspectMethod("register")
	public User register(String email,String passwd,String name) {
			...	
		}
	}

编写切面方法

@Aspect
@Component
public class MetricAspect {
	@Around("@annotation(method1)")
	public Object metric(ProceedingJoinPoint joinPoint,AspectMethod method1) throws Throwable {
		String name = method1.value();
		long start = System.currentTimeMilllis();
		try {
			System.err.println("我在register之前");
			return joinPint.proceed();
		}finally {
			long t = System.currentTimeMillis() - start;
			System.err.println("[AspectMethod]" + name + ":" + t + "ms");
			}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值