Spring AOP开发时如何得到某个方法内调用的方法的代理对象?

Spring AOP开发时如何得到某个方法内调用的方法的代理对象?

问题阅读起来拗口,看代码

在方法中调用其他方法很常见,也经常使用,如果在一个方法内部调用其他方法,比如

 public class UserServiceImpl implements UserService{
    @Override
    public void register(User user) {
        System.out.println("rg.Service.UserServiceImpl.register");
        this.login("SY","45452");
    }

    @Override
    public Boolean login(String name, String password) {
        System.out.println("rg.Service.UserServiceImpl.login "+name+" "+password );
        return true;
    }


}

我在这里调用了register中调用了login方法,那么我能获得login()这个被代理过的方法吗?

这是执行的代理方法

对所有login都执行代理

@Aspect
public class MyAspect {

   @Around("execution(* login(..))")
public Object ServiceAspect(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("MyAspect.ServiceAspect");
        Object ret=joinPoint.proceed();
        return ret;
    }
}

Spring配置文件,声明下类

<bean id="ExMethod" class="org.ExMerhod.UserServiceImpl"/>

如果得到了login()这个被代理过的方法会打印出MyAspect.ServiceAspect

执行下测试

public class TestExMethod {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("/ApplicationContext2.XML");
        UserService userService= (UserService) context.getBean("ExMethod");
        userService.login("SY","1223456");
        userService.register(new User());
    }
}

结果

image-20210601195400225

我们只看到了rg.Service.UserServiceImpl.login的方法被代理,并没有看到我们在register中的方法被代理

这就时是问题所在

从测试中的工厂得到的ExMethod的是被代理过的方法,而在代理过的方法内的方法是被调用的那个类的方法,而不是代理过的方法,所以不会被执行增强方法。

image-20210601200515374

所以我们需要让这个方法得到代理的对象即可

由于Spring工厂是一个超级重量级资源,所以我们使用ApplicationContextAware获得已经创建的工厂

具体代码如下

package org.ExMerhod;
import org.User;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class UserServiceImpl implements UserService,ApplicationContextAware{
private ApplicationContext contextAware;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.contextAware= applicationContext;
    }
    @Override
    public void register(User user) {
        System.out.println("rg.Service.UserServiceImpl.register");
        //注意,方法得到了工厂的创建的对象
        UserService userService= (UserService) contextAware.getBean("ExMethod");
        userService.login("SY","45452");

    }

    @Override
    public Boolean login(String name, String password) {
        System.out.println("rg.Service.UserServiceImpl.login "+name+" "+password );
        return true;
    }


}

这次我们从工厂获得了代理对象再执行一次试试

image-20210601201004330

可以看到,方法中的方法被代理了,问题也就解决了

posted on 2021-06-01 20:13  NathenJames  阅读(614)  评论(0编辑  收藏  举报