步骤
1.在配置文件中开启注解扫描,和代理类对象
2.给增强类和被增强类添加注解(放进ioc容器)
3.给增强类添加@aspect注解(声明这是一个增强类)
4.给增强类中的方法添加 @before 和@after注解(使用切入点表达式,告诉要增强哪个类中的哪个方法)
1 切入点表达式 告知要增强哪个类中的哪个方法
execution(返回类型 *号表示所有的类型
空格
包名 表示需要拦截的包名 com.atguigu.dao
第二个*号 表示com.atguigu.dao下的所有类
*(..) *号表示该类 中的所有方法,后面()是参数,..代表任何参数
)
增强com.atguigu.dao.bookdao类中的add方法
execution(* com.atguigu.dao.*.*(..))
增强com.atguigu.dao包中所有的方法
execution(* com.atguigu.dao.*.*(..))
步骤:
1.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/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
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.testdemo.service"></context:component-scan>
<!--开启代理类对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
2.给增强类和被增强类添加注解 (将他们放进ioc容器中)
被增强类
调用被增强方法(只能用接口接收,因为被增强类已经被增强了,和原来的被增强类已经不一样了,相当于是兄弟关系)
如果直接getbean获取,则第二个参数只能是接口.class
第一个参数,被增强之后的类虽然和原来的类不一致了,但是类名是没有变的,可以只写类名
package com.testdemo.service;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Component
public class User {
public void add()
{
System.out.println("user的原生方法");
}
}
增强类
package com.testdemo.service;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
public class Userplus {
}
3.在增强类上添加注解@Aspect,声明为切面类
package com.testdemo.service;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class Userplus {
}
4.在增强类中写增强的方法
package com.testdemo.service;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class Userplus {
@Before("execution(* com.testdemo.service.User.add(..))")
public void before()
{
System.out.println("在add方法之前执行Before");
}
@After("execution(* com.testdemo.service.User.add(..))")
public void after()
{//在方法执行之后执行
System.out.println("在add方法之后After");
}
@AfterReturning("execution(* com.testdemo.service.User.add(..))")
public void afterreturning()
{//在方法返回之后执行
System.out.println("在add方法之后AfterReturning");
}
//当add方法有异常才会执行
@AfterThrowing("execution(* com.testdemo.service.User.add(..))")
public void afterthrowing()
{
System.out.println("在add方法之后AfterThrowing");
}
@Around("execution(* com.testdemo.service.User.add(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("在add方法之前Around");
//被增强的方法
proceedingJoinPoint.proceed();
System.out.println("在add方法之后Around");
}
}
5.获取被增强类,并调用方法
package com.testdemo.service;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test01 {
public static void main(String[] args) {
ApplicationContext context =new ClassPathXmlApplicationContext("demo1.xml");
User user =(User) context.getBean("user");
user.add();
}
}
输出:
切入点表达式注解@Pointcut(将切入点表达式作为@pointcut的value 以后要使用切入点表达式,就可以直接@pointcut)
public class Userplus {
@Pointcut(value="execution(* com.testdemo.service.User.add(..))")
public void pointdemo1() {
}
@Before("pointdemo1()")
public void before()
{
System.out.println("在add方法之前执行Before");
}
@order()注解
当有多个类都增强了同一个方法时,可以使用这个注解决定增强的先后顺序
括号中要填数字,数字越小,越先执行
package com.testdemo.service;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect
@Component
@Order(0)
public class Userplus2 {
@Pointcut(value="execution(* com.testdemo.service.User.add(..))")
public void pointdemo1() {
}
@Before("pointdemo1()")
public void before()
{
System.out.println("plus2在add方法之前执行Before");
}
}