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());
}
}

結果

我們只看到了rg.Service.UserServiceImpl.login的方法被代理,並沒有看到我們在register中的方法被代理

這就時是問題所在

從測試中的工廠得到的ExMethod的是被代理過的方法,而在代理過的方法內的方法是被呼叫的那個類的方法,而不是代理過的方法,所以不會被執行增強方法。

所以我們需要讓這個方法得到代理的物件即可

由於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;
} }

這次我們從工廠獲得了代理物件再執行一次試試

可以看到,方法中的方法被代理了,問題也就解決了