Spring Boot启用AOP
1.引入AOP依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.定义目标对象
定义接口
public interface MyService{
void test();
}
定义实现类
@Service
public class MyServiceImpl implements MyService{
public void test(){
System.out.println("运行test方法");
}
}
3.定义切面类并指定切点
@Aspect
public class MyAspect{
@Pointcut("execution(* com.example.aop.service.impl.MyServiceImpl.test())")
public void pointCut(){
}
@Before("pointCut()")
public void before(){
System.out.println("执行before()方法");
}
}
4.将切面注入IOC容器
@Configuration
public class MyConfig{
@Bean
public MyAspect myAspect(){
return new MyAspect();
}
}
5.Controller层调用
@Controller
public class MyController{
@Autowired
private MyService myService;
@RequestMapping("test")
@ResponseBody
public String test(){
myService.test();
return "ok";
}
}
需要注意的问题
目标对象需要注入到IOC容器中,IOC容器在初始化bean时会判断这个bean是否需要代理,如果需要代理那么以后自动注入的bean将会是原来bean的代理对象。参见源码
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}