示例1
项目结构
.
├── build.gradle
└── src
└── main
├── java
│ └── demo
│ ├── Main.java
│ ├── TestAspect.java
│ └── TestBean.java
└── resources
build.gradle
gradle 中引入了如下依赖:
dependencies {
compile group: 'org.springframework', name: 'spring-core', version: '5.0.6.RELEASE'
compile group: 'org.springframework', name: 'spring-context', version: '5.0.6.RELEASE'
compile group: 'org.springframework', name: 'spring-aop', version: '5.0.6.RELEASE'
compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.9.1'
compile group: 'junit', name: 'junit', version: '4.12'
}
TestBean.java
TestBean 类内容如下:
package demo;
import org.springframework.stereotype.Component;
@Component
public class TestBean {
public void hello() {
System.out.println("hello");
}
}
TestAspect.java
TestAspect 类定义了切面,内容如下:
package demo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* @Aspect 和 @Component 都要有
*/
@Aspect
@Component
public class TestAspect {
// 定义切点(切入位置)
@Pointcut("execution(* demo.TestBean.*(..))")
private void pointcut(){}
@Before("pointcut()")
public void before(JoinPoint joinPoint){
System.out.println("我是前置通知");
}
}
Main.java
Main 类内容:
package demo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan
@EnableAspectJAutoProxy // 要加上这个
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Main.class);
TestBean testBean = ctx.getBean(TestBean.class);
testBean.hello();
}
}
执行结果
Main 类执行结果:
我是前置通知
hello
示例2:如果切面类没有 @Component
如果没有 @Component ,那么切面无效;如果切面类无法被扫描到,切面也是无效的。
项目结构
.
├── build.gradle
└── src
└── main
├── java
│ ├── demo01
│ │ ├── Main.java
│ │ └── TestBean.java
│ └── demo02
│ └── TestAspect.java
└── resources
TestBean.java
TestBean 类内容如下:
package demo01;
import org.springframework.stereotype.Component;
@Component
public class TestBean {
public void hello() {
System.out.println("hello");
}
}
TestAspect.java
TestAspect 类挪到了 demo02 包,并去掉了 @Component:
package demo02;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
public class TestAspect {
// 定义切点(切入位置)
@Pointcut("execution(* demo01.TestBean.*(..))")
private void pointcut(){}
@Before("pointcut()")
public void before(JoinPoint joinPoint){
System.out.println("我是前置通知");
}
}
Main.java
如果 Main 类内容如下,切面是无效的:
package demo01;
import demo02.TestAspect;
import org.springframework.context.annotation.*;
@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Main.class);
TestBean testBean = ctx.getBean(TestBean.class);
testBean.hello();
}
}
改成下面这样子,就行了:
package demo01;
import demo02.TestAspect;
import org.springframework.context.annotation.*;
@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class Main {
// 让切面类生成bean,以让切面生效
@Bean
public TestAspect testAspect() {
return new TestAspect();
}
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Main.class);
TestBean testBean = ctx.getBean(TestBean.class);
testBean.hello();
}
}
运行结果:
我是前置通知
hello