這篇文章主要介紹如何解決spring AOP中自身方法調用無法應用代理的問題,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
public class MyServiceImpl implements MyService {
public void do(){
//the transaction annotation won't work if you directly invoke handle() method with 'this'
this.handle();
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void handle() {
//sth with transaction
}
}如果直接調用this的handle()方法則事務無法生效,原因是spring的AOP是通過代理實現的,像這樣直接調用本對象的方法是不會應用代理的。
public class MyServiceImpl implements MyService {
@Autowired
private MyService myService;
public void do(){
//use myService object
myService.handle();
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void handle() {
//sth. with transaction
}
}public class MyServiceImpl implements MyService {
public void do(){
//fetch current proxy objet from AopContext
((MyService)AopContext.currentProxy()).handle();
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void handle() {
//sth with transaction
}
}注意,原生的AspectJ是不會有這種自身調用的問題的,因為它不是基于代理的AOP框架。
基于 proxy 的 spring aop 帶來的內部調用問題可以使用 AopContext.currentProxy() 強轉為當前的再調用就可以解決了
例如:
錯誤用法:
public Account getAccountByName2(String userName) {
return this.getAccountByName(userName);
}修改為:
public Account getAccountByName2(String userName) {
return ((AccountService)AopContext.currentProxy()).getAccountByName(userName);
}另外注意:要設置aop實體暴露出來。在springboot的application.java里面加上
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
利用初始化方法在目標對象中注入代理對象
在目標對象類中注入spring上下文,通過context獲取代理對象,并調用代理對象的方法。
注意:該方案對于scope為prototype的bean無法適用,因為每次獲取bean時都返回一個新的對象。
方法2.1:
//延遲加載方式
private TestService testService;
@Autowired
@Lazy
public void setTestService(TestService testService) {
this.testService = testService;
}方法2.2:
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import com.blog.common.aop.service.TestService;
@Service
public class TestServiceImpl implements TestService {
@Autowired
private ApplicationContext context;
private TestService proxyObject;
@PostConstruct
// 初始化方法,在IOC注入完成后會執行該方法
private void setSelf() {
// 從spring上下文獲取代理對象(直接通過proxyObject=this是不對的,this是目標對象)
// 此種方法不適合于prototype Bean,因為每次getBean返回一個新的Bean
proxyObject = context.getBean(TestService.class);
}
public void methodA() throws Exception {
System.out.println("method A run");
System.out.println("method A 中調用method B,通過注入的代理對象,調用代理對象的方法,解決內部調用實現的問題。");
proxyObject.methodB(); //調用代理對象的方法,解決內部調用失效的問題
}
public void methodB() {
System.out.println("method B run");
}
}以上是“如何解決spring AOP中自身方法調用無法應用代理的問題”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。