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;
}
}
這次我們從工廠獲得了代理物件再執行一次試試
可以看到,方法中的方法被代理了,問題也就解決了