为了账号安全,请及时绑定邮箱和手机立即绑定

@Before、@After注解的方法都不执行

@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方法都没有执行

正在回答

3 回答

他织入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代理的话,就不是继承目标对象了,是实现目标对象的接口,然后把接口的实现注入到代理类的属性中,走回调的话就是调用这个属性的方法。

0 回复 有任何疑惑可以回复我~

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>


0 回复 有任何疑惑可以回复我~

你将private void printInteger(Integer i)方法写到service层,类上加上注解@Service,然后再从Controller层用@Autowried注入调用就行了.

匹配表达式改成within(com.imooc.miaosha.service.*)

0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

@Before、@After注解的方法都不执行

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信