笑傲江湖3955759
2018-07-06 11:40
@Aspect
@Component
public class AspectConfig {
@Pointcut("args(Integer) && within(com.imooc.miaosha.controller.*)")
public void matchArgs() {}
@Before("matchArgs()")
public void before_1() {
System.out.println("####before1");
}
@After("matchArgs()")
public void after_1() {
System.out.println("####after1");
}
}package com.imooc.miaosha.controller;
@Controller
@RequestMapping("/demo")
public class SampleController {
@RequestMapping("/hello")
@ResponseBody
public Result<String> home() {
System.out.println("hello");
printInteger(100);
return Result.success("Hello,world");
}
private void printInteger(Integer i) {
System.out.println("this is "+i);
}
}运行结果:访问http://localhost:8080/demo/hello,正常运行,没有报异常,但是AspectConfig类中的before_1、after_1方法都没有执行
他织入AOP增强代码的时候相当于就是这样的一个结构
public class Proxy extend SampleController{
@Overwired
public Result<String> home() {
System.out.println("hello");
super.printInteger(100);
return Result.success("Helloworld");
}
@Overwired
private void printInteger(Integer i) {
before_1();
super.printInteger(i);
after_1();
}
public void before_1() {
System.out.println("####before1");
}
public void after_1() {
System.out.println("####after1");
}
}
大体上这个意思,这个是CGLIB代理,within是使用CGLIB代理的, 如果时JDK代理的话,就不是继承目标对象了,是实现目标对象的接口,然后把接口的实现注入到代理类的属性中,走回调的话就是调用这个属性的方法。
sampleController本身调用home()方法时是CGLIB代理对象,但是执行home()方法时你切面advice没有做增强处理,然后proxy代理类再回调目标对象类的printInteger(Integer i)方法,这个时候也就是IOC容器中的sampleController 的 bean本身。所以自然不会触发advice方法。
几个解决办法。
1.从applicationContext(beanFactory)中重新获取sampleController类的bean,spring在注入的时候会检查bean是否由代理类,如果有的话就会赋值为代理类,这个时候你就重新得到了代理对象了,然后在方法内部用代理对象重新printInteger(Integer i)方法。
2.开启代理暴露。
注解形式:@EnableAspectJAutoProxy(exposeProxy=true,proxyTargetClass=true);
xml形式:
<aop:config expose-proxy="true"></aop:config>
你将private void printInteger(Integer i)方法写到service层,类上加上注解@Service,然后再从Controller层用@Autowried注入调用就行了.
匹配表达式改成within(com.imooc.miaosha.service.*)
探秘Spring AOP
61197 学习 · 64 问题
相似问题