导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
这里是以勇士冒险做例子
两个接口
勇士 冒险
public interface Knights {
void embarkOnQuest();
}
public interface Quest {
void embark();
}
三个实现类
@Component
public class BraveKnight implements Knights {
private Quest quest;
public BraveKnight(@Qualifier("slayDragonQuest") Quest quest){
this.quest=quest;
}
@Override
public void embarkOnQuest() {
quest.embark();
}
}
@Component
public class RescueDamselQuest implements Quest {
@Override
public void embark() {
System.out.println("Embarking on a quest to rescue the damsel.");
}
}
@Component
public class SlayDragonQuest implements Quest {
public void embark() {
System.out.println("Embarking on quest to slay the dragon!");
}
}
需要注意的是实现quest的接口有两个实现类,不能自动注入,所以需要@Qualifier("slayDragonQuest")
注入特定组件
切面拦截
这里要注意!!!!!!!!!我开始用里面自带的aspect建立了一个aspect后来又改了class 但是这样我的aop就用不了了,必须直接建立class,而不能建立了aspect然后再把aspect改成class,具体原因还不清楚,但这问题很迷,切记!!!!!
@Component
@Aspect
public class Minstrel {
@Pointcut("execution(* com.example.springbootaopdemo.entity.SlayDragonQuest.embark()) ")
public void embark(){}
@Before("embark()")
public void singBeforeQuest(){
System.out.println("Fa la la,the knight is so brave");
}
@After("embark()")
public void singAfterQuest(){
System.out.println("Hee Hee Hee,the brave knight did embark on a quest");
}
}
@Component
@Aspect
这两个注解表示这是个实现切面的类,里面配置了切点,通知
这里使用一个空方法去标记pointcut,然后下面通知去用这个方法,也可以直接用execution(* com.example.springbootaopdemo.entity.SlayDragonQuest.embark())
去替代embark()
Test测试
@SpringBootTest
class SpringbootAopDemoApplicationTests {
@Autowired
Knights knights;
@Test
void contextLoads() {
}
@Test
void testAop(){
knights.embarkOnQuest();
}
}
自动装配,然后测试方法有没有被拦截
over。