使用注解来创建切面是AspectJ5所引入的关键特性。
常用的注解
注解 | 描述 |
---|---|
@AspectJ | 标注一个切面 |
@Pointcut | 定义一个可以在@AspectJ切面内可重用的切点,切点的名称来源于注解所应用的方法名称,方法本身只是一个标识,供@pointcut注解依附 |
@Before | 标识前置通知方法 |
@After | 标识后置通知方法 |
@AfterReturning | 标识调用结果返回后,该方法被调用 |
@AfterThrowing | 标识调用抛出异常时,该方法被调用 |
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(* pray.wang.java..*.getName(..))")
public void log(){}
@Before("log()")
public void start(){
System.out.println("start invoke method");
}
@After("log()")
public void end(){
System.out.println("end invoke method");
}
@AfterReturning("log()")
public void ret(){
System.out.println("invoke method return");
}
@AfterThrowing("log()")
public void thr(){
System.out.println("invoke method error");
}
}
@AspectJ注解只是表明该类是一个切面,还需要在Spring中声明为一个Bean,最后还在Spring上下文中声明一个自动代理的Bean,该Bean知道如何把@AspectJ注解所标注的Bean转变为代理通知。
为此,Spring自带了名为AnnotationAwareAspectJAutoProxyCreator的自动代理创建类,我们可以在Spring上下文中把AnnotationAwareAspectJAutoProxyCreator注册为一个Bean,但是这种做法太麻烦。为了简化,Spring在aop命名空间中提供了一个自定义的配置元素—<aop:aspectj-autoproxy>
.
<aop:aspectj-autoproxy>将在Spring上下文中自动创建一个AnnotationAwareAspectJAutoProxyCreator类,他会自动代理一些Bean。
<aop:aspectj-autoproxy>
该元素等价于@EnableAspectJAutoProxy
注解
一个完整的Java配置注解的示例:
主函数类
public class JavaApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
PeopleService peopleService = applicationContext.getBean("peopleService", PeopleService.class);
System.out.println(peopleService.getPeople().toString());
peopleService.getPeople().getName();
}
}
配置类
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "pray.wang.java")
public class SpringConfig {
}
切面类
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(* pray.wang.java..*.getName(..))")
public void log(){}
@Before("log()")
public void start(){
System.out.println("start invoke method");
}
@After("log()")
public void end(){
System.out.println("end invoke method");
}
@AfterReturning("log()")
public void ret(){
System.out.println("invoke method return");
}
@AfterThrowing("log()")
public void thr(){
System.out.println("invoke method error");
}
}
<aop:aspect>
元素和@AspectJ
注解都是把一个POJO转变为一个切面的有效方式,但是<aop:aspect>
相对于@AspectJ
的一个明显的优势是我们不需要实现切面功能的源码。通过@AspectJ
,我们必须标注类和方法,他需要有源码。而<aop:aspect>
可以引用任意一个Bean。
标注引入
等价于<aop:declare-parents>的注解是@AspectJ的@DeclareParents。
网友评论